Skip to content

Commit

Permalink
Merge pull request #35 from Nounspace/hy_port_to_fidget_wrappers
Browse files Browse the repository at this point in the history
feat: port Layout PR to use frame wrappers
  • Loading branch information
j-paterson authored May 13, 2024
2 parents 79e3e83 + 773fb54 commit ef467f4
Show file tree
Hide file tree
Showing 19 changed files with 505 additions and 354 deletions.
8 changes: 4 additions & 4 deletions src/app/sandbox/fidgets/[fidgetName]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client"
import React from "react";
import FidgetViewer from "@/common/fidgets/FidgetViewer";
import CompleteFidgets from "@/fidgets";
import { GenericFidget } from "@/common/fidgets/makeFidget";
import { CompleteFidgets } from "@/fidgets";
import { FidgetModule } from "@/common/fidgets";

type PageParams = {
params: {
Expand All @@ -11,12 +11,12 @@ type PageParams = {
};

export default function Page({ params }: PageParams) {
const fidget = CompleteFidgets[params.fidgetName] as GenericFidget;
const fidgetModule = CompleteFidgets[params.fidgetName] as FidgetModule;

return (
<>
{
fidget ? <FidgetViewer fidget={fidget} /> : <div>Error Loading Fidget</div>
fidgetModule ? <FidgetViewer fidgetModule={fidgetModule} /> : <div>Error Loading Fidget</div>
}
</>
);
Expand Down
10 changes: 5 additions & 5 deletions src/common/fidgets/FidgetViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
"use client"
import React, { useState } from "react";
import { FidgetConfig, FidgetSettings, GenericFidget } from "@/common/fidgets/makeFidget";
import { reduce } from "lodash";
import { FidgetWrapper, FidgetWrapperConfig } from "@/common/fidgets/FidgetWrapper";
import { FidgetConfig, FidgetModule, FidgetSettings } from ".";


export default function FidgetViewer({ fidget }: { fidget: GenericFidget }) {
export default function FidgetViewer({ fidgetModule }: { fidgetModule: FidgetModule }) {
const defaultConfig: FidgetWrapperConfig = {
editConfig: fidget.editConfig,
editConfig: fidgetModule.editConfig,
fidgetConfig: {
editable: true,
size: [1, 2],
settings: reduce(
fidget.editConfig.fields,
fidgetModule.editConfig.fields,
(acc, f) => ({
...acc,
[f.fieldName]: f.default || null,
Expand All @@ -34,7 +34,7 @@ export default function FidgetViewer({ fidget }: { fidget: GenericFidget }) {
<FidgetWrapper
config={config}
saveConfig={saveConifg}
fidget={fidget}
fidget={fidgetModule.fidget}
/>
);
}
59 changes: 24 additions & 35 deletions src/common/fidgets/FidgetWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
"use client"
import React, { useState } from "react";
import { FidgetConfig, FidgetEditConfig, FidgetSettings } from "@/common/fidgets/makeFidget";
import { Card, CardContent, CardHeader } from "../ui/atoms/card";
import { Button } from "../ui/atoms/button";
import FidgetWrapperEditMode from "./FidgetWrapperEditMode";
import { toast } from "sonner";

export type FidgetWrapperConfig = {
fidgetConfig: FidgetConfig<FidgetSettings>;
readonly editConfig: FidgetEditConfig;
};
import { FidgetConfig, FidgetSettings, FidgetDetails } from ".";
import { FaGear } from "react-icons/fa6";

type FidgetWrapperProps = {
fidget: React.FC<FidgetSettings>;
config: FidgetWrapperConfig;
config: FidgetDetails;
saveConfig: (conf: FidgetConfig<FidgetSettings>) => Promise<boolean>
};

export function FidgetWrapper({ fidget, config, saveConfig }: FidgetWrapperProps) {
console.log(fidget);
const [saving, setSaving] = useState(false);
const [editing, setEditing] = useState(false);
const [viewEditor, setViewEditor] = useState(false);
const [localConfig, setLocalConfig] = useState({
...config.fidgetConfig,
const [localConfig, setLocalConfig] = useState<FidgetConfig<FidgetSettings>>({
...config.instanceConfig,
});
const setSettings = (settings: FidgetSettings) => {
setLocalConfig({
Expand All @@ -42,39 +37,33 @@ export function FidgetWrapper({ fidget, config, saveConfig }: FidgetWrapperProps
}
}

// TO DO: Add support for resizing the Fidget
// TO DO: Add support to set size of Fidget to size defined in the config

return (
<Card className="max-w-sm col-span-1">
<CardHeader>
{
editing ?
<Button
className="w-full"
onClick={() => setViewEditor(!viewEditor)}
>
{ viewEditor ? "View Fidget" : "View Editor" }
</Button> : null
}
{ config.fidgetConfig.editable ?
<Button
className="w-full"
onClick={toggleEditing}
>
{ editing ? "Save": "Edit" }
</Button> : null
}
</CardHeader>
<CardContent>
<Card className="size-full">
{
editing ?
<Button
className="flex items-center justify-center opacity-0 hover:opacity-100 duration-500 absolute inset-0 z-10 flex bg-slate-400 bg-opacity-50"
onClick={() => setViewEditor(!viewEditor)}
>
{ viewEditor ? "View Fidget" : "View Editor" }
</Button> : null
}
{ config.instanceConfig.editable ?
<div className = "flex items-center justify-center opacity-0 hover:opacity-50 duration-500 absolute inset-0 z-10 flex bg-slate-400 bg-opacity-50 rounded-md">
<button onClick={toggleEditing} className = "absolute flex-1 size-1/12 opacity-50 hover:opacity-100 duration-500 z-10 flex justify-center items-center text-white font-semibold text-2xl">
<FaGear />
</button>
</div> : null
}
<CardContent className="size-full">
{
editing && viewEditor ?
<FidgetWrapperEditMode
editConfig={config.editConfig}
settings={localConfig.settings}
setSettings={setSettings}
/>
: fidget(config.fidgetConfig.settings)
: fidget(config.instanceConfig.settings)
}
</CardContent>
</Card>
Expand Down
59 changes: 59 additions & 0 deletions src/common/fidgets/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export interface FidgetSettings {}

export type FidgetConfig<S extends FidgetSettings = FidgetSettings> = {
editable: boolean;
settings: S;
};

export type FidgetFieldConfig = {
readonly fieldName: string;
readonly validator?: (value) => boolean;
// This should be changed to a set of allowed input selectors
readonly inputSelector: React.FC;
readonly default?: any;
readonly required: boolean;
};

export type FidgetEditConfig = {
fields: FidgetFieldConfig[];
size: {
minHeight: NumericRange<1,36>;
maxHeight: NumericRange<1,36>;
minWidth: NumericRange<1,36>;
maxWidth: NumericRange<1,36>;
}
};

export interface FidgetDetails<S extends FidgetSettings = FidgetSettings> {
editConfig: FidgetEditConfig;
instanceConfig: FidgetConfig<S>;
id: string;
}

export interface LayoutFidgetConfig {}

export interface LayoutFidgetDetails {
layoutFidget: string;
layoutConfig: LayoutFidgetConfig;
}

export interface FidgetModule<P = unknown> {
fidget: React.FC<P>;
editConfig: FidgetEditConfig;
}

interface LayoutFigetProps {
layoutConfig: LayoutFidgetConfig;
fidgets: {
[key: string]: ReactNode;
};
isEditable: boolean;
}

const LayoutFidgetDefaultProps = {
fidgets: object,
layoutConfig: object,
isEditable: false,
}

export interface LayoutFiget<P extends LayoutFigetProps = LayoutFidgetDefaultProps> extends React.FC<P> {}
43 changes: 0 additions & 43 deletions src/common/fidgets/makeFidget.tsx

This file was deleted.

3 changes: 3 additions & 0 deletions src/common/lib/utils/divIdGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function randDivId(): string {
return Math.random().toString(36).replace(/[^a-z]+/g, '').substring(2, 10);
}
2 changes: 1 addition & 1 deletion src/common/ui/atoms/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={mergeClasses("p-6 pt-0", className)} {...props} />
<div ref={ref} className={mergeClasses("", className)} {...props} />
))
CardContent.displayName = "CardContent"

Expand Down
79 changes: 79 additions & 0 deletions src/common/ui/templates/Space.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { FidgetConfig, FidgetSettings, LayoutFidgetDetails } from '@/common/fidgets';
import React from 'react';
import { CompleteFidgets, LayoutFidgets } from '@/fidgets';
import { mapValues } from 'lodash';
import { FidgetWrapper } from '@/common/fidgets/FidgetWrapper';

export type SpaceConfig = {
fidgetConfigs: {
[key: string]: {
instanceConfig: FidgetConfig<FidgetSettings>;
fidgetName: string;
id: string;
};
}
layoutID: string;
layoutDetails: LayoutFidgetDetails;
}

type SpaceArgs = {
config: SpaceConfig;
isEditable: boolean;
saveConfig: (config: SpaceConfig) => Promise<boolean>;
}

export default function Space({ config, isEditable, saveConfig }: SpaceArgs){
const LayoutFidget = LayoutFidgets[config.layoutDetails.layoutFidget];
const fidgets = mapValues(config.fidgetConfigs, (details, key) => FidgetWrapper({
fidget: CompleteFidgets[details.fidgetName].fidget,
config: {
id: details.id,
instanceConfig: {
editable: isEditable,
settings: details.instanceConfig.settings,
},
editConfig: CompleteFidgets[details.fidgetName].editConfig,
},
saveConfig: async (newInstanceConfig: FidgetConfig<FidgetSettings>) => {
return await saveConfig({
layoutID: config.layoutID,
layoutDetails: config.layoutDetails,
fidgetConfigs: {
...config.fidgetConfigs,
[key]: {
instanceConfig: newInstanceConfig,
id: details.id,
fidgetName: details.fidgetName,
},
},
})
},
}));

function saveLayout(layout) {
return saveConfig({
layoutID: config.layoutID,
fidgetConfigs: config.fidgetConfigs,
layoutDetails: {
...config.layoutDetails,
layoutConfig: {
...config.layoutDetails.layoutConfig,
layout: layout,
},
},
});
}

console.log(fidgets);

return (
<LayoutFidget
layoutConfig={{
...config.layoutDetails.layoutConfig,
onLayoutChange: saveLayout,
}}
fidgets={fidgets}
isEditable={isEditable}
/>
);
}
Loading

0 comments on commit ef467f4

Please sign in to comment.