From 4d08f9192105be53e2a57bc2bc0d63c616bea6fb Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 15 Jun 2023 05:18:45 -0600 Subject: [PATCH] adds accordion, details query syntax, various small tweaks --- project-warstone/query syntax | 50 +++++++++ .../components/SchemaBuilder/field-editor.tsx | 16 ++- .../src/components/SchemaBuilder/index.tsx | 4 +- .../SchemaBuilder/schema-viewer.tsx | 32 +++--- .../components/SchemaBuilder/type-editor.tsx | 13 ++- .../components/SchemaBuilder/value-field.tsx | 2 +- .../src/constants/TemplateTypes.ts | 9 ++ project-warstone/src/index.css | 14 ++- project-warstone/src/lib/accordion/index.tsx | 68 ++++++++++++ project-warstone/src/types/schema.ts | 1 + project-warstone/tailwind.config.js | 3 + project-warstone/temp.json | 102 ++++++++++++++++++ 12 files changed, 291 insertions(+), 23 deletions(-) create mode 100644 project-warstone/query syntax create mode 100644 project-warstone/src/lib/accordion/index.tsx create mode 100644 project-warstone/temp.json diff --git a/project-warstone/query syntax b/project-warstone/query syntax new file mode 100644 index 0000000..de5c07e --- /dev/null +++ b/project-warstone/query syntax @@ -0,0 +1,50 @@ +Start query: ? + - by default, queries search the publication +Query current object: ^ +Access child: . + - this also maps over all items in a list and returns a list of the relevant children + - if the parent is a list, it will return a list of just the specified child +Select: [] + - Selects any of the items that matches the provided selector + - Providing a number selects the ordinal item in the list + - Providing a comparator selects items that match the comparator + - Selectors can be separated by either commas for "and" or slashes for "or", but not both +Comparators: + = is similar to + == is exactly the same + > greater than + < less than + >= greater than or equal to + <= less than or equal to + !! is true/exists + ! is not + / or, allows matching one or more comparators at the same time +Combiner: () + - Will only select items that match all of the selectors + - Selectors can be separated by either commas for "and" or slashes for "or", but not both + +--Templating-- +insertion: {{}} + - Allows for queries to be wrapped in a templated string + - Can be either a direct query or used in combination with the "_" character to reference a single query +single query: < void; field: FieldType; fieldName: string; + deleteField: (arg: string) => void; } -export const FieldEditor: FC = ({ update, field, fieldName }) => { +export const FieldEditor: FC = ({ update, field, fieldName, deleteField }) => { const { bindProperty, bindPropertyCheck } = useObjectStateWrapper(field, (e) => update(typeof e === 'function' ? e(field) : e)) const shouldShowValueField = useCallback(() => fieldTypesWithValues.includes(field.type) || field.isConstant, [field.isConstant, field.type]); @@ -22,7 +24,7 @@ export const FieldEditor: FC = ({ update, field, fieldName }) => { return (
  • {fieldName}

    -
    +
    + +

    Minimum and Limit apply to the number of entries allowed for this field, not the maximum and minimum value. Set the minimum to 0 to make a field optional. Set the limit to 0 to allow for unlimited entries.

    +
    +
  • ) diff --git a/project-warstone/src/components/SchemaBuilder/index.tsx b/project-warstone/src/components/SchemaBuilder/index.tsx index e910ec5..829a7bf 100644 --- a/project-warstone/src/components/SchemaBuilder/index.tsx +++ b/project-warstone/src/components/SchemaBuilder/index.tsx @@ -135,8 +135,7 @@ export const SchemaBuilder: FC = () => {
    - -
    +
    +
    ) diff --git a/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx b/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx index a40a9f3..0430a33 100644 --- a/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx +++ b/project-warstone/src/components/SchemaBuilder/schema-viewer.tsx @@ -1,6 +1,7 @@ import { FC, useCallback } from 'react' import { FieldType, FieldTypes, Schema, TypeType, fieldTypesWithValues } from '../../types/schema' import { Truncate } from '../Poppables/truncation'; +import { Accordion, AccordionContent } from '../../lib/accordion'; interface IProps { schema: Schema; @@ -40,25 +41,30 @@ export const SchemaViewer: FC = ({ schema, onTypeClick }) => {

    Types

    -
      +
        {Object.entries(schema.types).map(([typeKey, type]) => (
      • onTypeClick && onTypeClick(typeKey, type)} + // onClick={() => onTypeClick && onTypeClick(typeKey, type)} data-clickable={!!onTypeClick} - className="odd:bg-black/50 p-2 data-[clickable=true]:cursor-pointer" + className="odd:bg-black/50 p-2 group overflow-hidden" > -

        {typeKey}

        -
        - {Object.entries(type).map(([fieldKey, field]) => ( -
        -

        {fieldKey}

        -

        {field.type}

        -

        Maximum entries: {field.limit === 0 ? 'unlimited ' : field.limit}

        - {(field.isConstant || fieldTypesWithValues.includes(field.type)) &&

        {createValueLable(field)} {field.value}

        } + {typeKey}

        } + > + +
        + {Object.entries(type).map(([fieldKey, field]) => ( +
        +

        {fieldKey}

        +

        {field.type}

        +

        Maximum entries: {field.limit === 0 ? 'unlimited ' : field.limit}

        + {(field.isConstant || fieldTypesWithValues.includes(field.type)) &&

        {createValueLable(field)} {field.value}

        } +
        + ))}
        - ))} -
        + +
      • ))}
      diff --git a/project-warstone/src/components/SchemaBuilder/type-editor.tsx b/project-warstone/src/components/SchemaBuilder/type-editor.tsx index c4348db..e917a9a 100644 --- a/project-warstone/src/components/SchemaBuilder/type-editor.tsx +++ b/project-warstone/src/components/SchemaBuilder/type-editor.tsx @@ -30,6 +30,7 @@ export const TypeEditor: FCC = ({ saveType, name, type: passedType }) => value: '', isConstant: false, limit: 1, + minimum: 1, } }); resetPropertyName(); @@ -43,14 +44,22 @@ export const TypeEditor: FCC = ({ saveType, name, type: passedType }) => passedType && setType(passedType); }, [passedType, setType]); + const deleteField = useCallback((name: string) => { + setType(t => { + const fields = {...t}; + delete fields[name]; + return fields; + }) + }, [setType]) + return (

      {passedType ? 'Editing' : 'Creating'} type "{name}"

        - {Object.entries(type).filter(([k]) => !constantProperties.includes(k)).map(([key, value]) => ( - + {Object.entries(type).reverse().filter(([k]) => !constantProperties.includes(k)).map(([key, value]) => ( + ))}
      diff --git a/project-warstone/src/components/SchemaBuilder/value-field.tsx b/project-warstone/src/components/SchemaBuilder/value-field.tsx index 186fa96..81603d8 100644 --- a/project-warstone/src/components/SchemaBuilder/value-field.tsx +++ b/project-warstone/src/components/SchemaBuilder/value-field.tsx @@ -61,7 +61,7 @@ export const ValueField: FC = ({ type, bind }) => { ) case FieldTypes.text: return ( - + ) case FieldTypes.select: return ( diff --git a/project-warstone/src/constants/TemplateTypes.ts b/project-warstone/src/constants/TemplateTypes.ts index 1bb6eb5..610ec82 100644 --- a/project-warstone/src/constants/TemplateTypes.ts +++ b/project-warstone/src/constants/TemplateTypes.ts @@ -5,12 +5,14 @@ export const TEMPLATE_TYPES: Record = { name: { isConstant: false, limit: 1, + minimum: 1, type: FieldTypes.text, value: '' }, body: { isConstant: false, limit: 0, + minimum: 1, type: FieldTypes['long text'], value: '' }, @@ -19,6 +21,7 @@ export const TEMPLATE_TYPES: Record = { steps: { isConstant: false, limit: 0, + minimum: 1, type: FieldTypes.type, value: 'section' } @@ -27,12 +30,14 @@ export const TEMPLATE_TYPES: Record = { name: { isConstant: false, limit: 1, + minimum: 1, type: FieldTypes.text, value: '' }, link: { isConstant: false, limit: 1, + minimum: 1, type: FieldTypes.text, value: '' }, @@ -41,6 +46,7 @@ export const TEMPLATE_TYPES: Record = { items: { isConstant: false, limit: 0, + minimum: 1, type: FieldTypes['long text'], value: '' } @@ -49,6 +55,7 @@ export const TEMPLATE_TYPES: Record = { columns: { isConstant: false, limit: 0, + minimum: 1, type: FieldTypes.any, value: '' } @@ -57,12 +64,14 @@ export const TEMPLATE_TYPES: Record = { rows: { isConstant: false, limit: 0, + minimum: 1, type: FieldTypes.type, value: 'tableRow' }, header: { isConstant: false, limit: 1, + minimum: 0, type: FieldTypes.type, value: 'tableRow' } diff --git a/project-warstone/src/index.css b/project-warstone/src/index.css index f760d46..f06fb8b 100644 --- a/project-warstone/src/index.css +++ b/project-warstone/src/index.css @@ -42,7 +42,11 @@ } button:not(.no-default) { - @apply interactive bg-olive-drab p-1 + @apply interactive p-1 + } + + button:not([class*="bg-"]):not(.no-default) { + @apply bg-olive-drab } .interactive { @@ -66,11 +70,14 @@ animation: fade 300ms forwards ease-in reverse; } - .trash-can, .anvil { + .trash-can, + .anvil { overflow: visible; } - .trash-can path.trash-lid, .anvil .anvil-base, .anvil .anvil-body { + .trash-can path.trash-lid, + .anvil .anvil-base, + .anvil .anvil-body { transition: 300ms transform, 300ms rotate, 300ms fill, 300ms stroke; } @@ -82,6 +89,7 @@ .anvil:hover .anvil-base { transform: translate(0px, 5%); } + .anvil:hover .anvil-body { transform: translate(0px, -5%); } diff --git a/project-warstone/src/lib/accordion/index.tsx b/project-warstone/src/lib/accordion/index.tsx new file mode 100644 index 0000000..8925b57 --- /dev/null +++ b/project-warstone/src/lib/accordion/index.tsx @@ -0,0 +1,68 @@ +import { FC, PropsWithChildren, ReactNode, useCallback, useState } from 'react' +import { FCC } from '../../types'; + +interface IProps { + expandOnHover?: boolean; + expanded?: boolean; + title?: ReactNode; +} + +export const Accordion: FCC = ({ children, expandOnHover, expanded, title }) => { + const [open, setOpen] = useState(false); + + return ( +
      !title && !expandOnHover && setOpen(!open)} + > + {!!title && ( +
      !expandOnHover && setOpen(!open)}> + {title} +
      + + +
      +
      + )} + {children} +
      + ) +} + +export const AccordionContent: FC = ({ children }) => { + const [height, setHeight] = useState(0); + + const updateRef = useCallback((node: HTMLDivElement | null) => { + if (node) { + setHeight(node.clientHeight) + } else { + setHeight(0) + } + }, []) + + const Child = () =>
      + {children} +
      + + return ( +
      + {} + +
      + ); +} \ No newline at end of file diff --git a/project-warstone/src/types/schema.ts b/project-warstone/src/types/schema.ts index fafa795..c594912 100644 --- a/project-warstone/src/types/schema.ts +++ b/project-warstone/src/types/schema.ts @@ -7,6 +7,7 @@ export type FieldType = { value: string; isConstant: boolean; limit: number; + minimum: number; }; export type TypeType = Record; diff --git a/project-warstone/tailwind.config.js b/project-warstone/tailwind.config.js index 74211b9..ef41752 100644 --- a/project-warstone/tailwind.config.js +++ b/project-warstone/tailwind.config.js @@ -50,6 +50,9 @@ export default { }, container: { center: true + }, + height: { + variable: 'var(--v-height)' } }, }, diff --git a/project-warstone/temp.json b/project-warstone/temp.json new file mode 100644 index 0000000..e90ad62 --- /dev/null +++ b/project-warstone/temp.json @@ -0,0 +1,102 @@ +{ + "id": "286f4c18-d280-444b-8d7e-9a3dd09f64ef", + "name": "Warhammer 40,000 10e v1", + "types": { + "Wargear_Profile": { + "name": { + "type": "text", + "value": "", + "isConstant": false, + "limit": 1, + "minimum": "1" + }, + "abilities": { + "type": "select", + "value": "Assault,Pistol,Rapid Fire,Torrent,Ignores Cover,Lethal Hits,Twin-linked,Lance,Indirect Fire,Blast,Melta,Precision,Heavy,Hazardous,Sustained Hits:Sustained Hits {{?^sustained_hits}},Extra Attacks,Devastating Wounds,Anti:Anti-{{_.keyword}} {{_.count}}+<