Skip to content

Commit

Permalink
Add a Left Sidebar for Placing Schemas #400 (#452)
Browse files Browse the repository at this point in the history
* TMP

* Remove original 'Add new field' Button

* TMP

* TMP

* add icon

* FIx drag position bug

* Minor fix

* Fix sidebar position

* Update snapshot

* Minor fix

* Update packages/ui/src/components/Designer/index.tsx

Co-authored-by: Peter Ward <pete@pennyblack.io>

---------

Co-authored-by: Peter Ward <pete@pennyblack.io>
  • Loading branch information
hand-dot and peteward committed Mar 22, 2024
1 parent 0dd5e00 commit 8ddfa7a
Show file tree
Hide file tree
Showing 28 changed files with 361 additions and 140 deletions.
2 changes: 1 addition & 1 deletion packages/common/src/schema.ts
Expand Up @@ -19,7 +19,6 @@ export const Dict = z.object({
notUniq: z.string(),
noKeyName: z.string(),
fieldsList: z.string(),
addNewField: z.string(),
editField: z.string(),
type: z.string(),
errorOccurred: z.string(),
Expand Down Expand Up @@ -76,6 +75,7 @@ export const Size = z.object({ height: z.number(), width: z.number() });
export const Schema = z
.object({
type: z.string(),
icon: z.string().optional(),
content: z.string().optional(),
position: z.object({ x: z.number(), y: z.number() }),
width: z.number(),
Expand Down
14 changes: 14 additions & 0 deletions packages/schemas/src/barcodes/propPanel.ts
Expand Up @@ -16,10 +16,14 @@ const defaultIncludetext = { includetext: DEFAULT_BARCODE_INCLUDETEXT };
const position = { x: 0, y: 0 };
const default40x20 = { width: 40, height: 20 };

const barcodeIcon =
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-barcode"><path d="M3 5v14"/><path d="M8 5v14"/><path d="M12 5v14"/><path d="M17 5v14"/><path d="M21 5v14"/></svg>';

const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'qrcode',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-qr-code"><rect width="5" height="5" x="3" y="3" rx="1"/><rect width="5" height="5" x="16" y="3" rx="1"/><rect width="5" height="5" x="3" y="16" rx="1"/><path d="M21 16h-3a2 2 0 0 0-2 2v3"/><path d="M21 21v.01"/><path d="M12 7v3a2 2 0 0 1-2 2H7"/><path d="M3 12h.01"/><path d="M12 3h.01"/><path d="M12 16v.01"/><path d="M16 12h1"/><path d="M21 12v.01"/><path d="M12 21v-1"/></svg>',
content: 'https://pdfme.com/',
position,
...defaultColors,
Expand All @@ -32,6 +36,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'japanpost',
icon: barcodeIcon,
content: '6540123789-A-K-Z',
position,
...defaultColors,
Expand All @@ -46,6 +51,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'ean13',
icon: barcodeIcon,
content: '2112345678900',
position,
...defaultColors,
Expand All @@ -60,6 +66,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'ean8',
icon: barcodeIcon,
content: '02345673',
position,
...defaultColors,
Expand All @@ -73,6 +80,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'code39',
icon: barcodeIcon,
content: 'THIS IS CODE 39',
position,
...defaultColors,
Expand All @@ -85,6 +93,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'code128',
icon: barcodeIcon,
content: 'This is Code 128!',
position,
...defaultColors,
Expand All @@ -98,6 +107,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'nw7',
icon: barcodeIcon,
content: 'A0123456789B',
position,
...defaultColors,
Expand All @@ -111,6 +121,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'itf14',
icon: barcodeIcon,
content: '04601234567893',
position,
...defaultColors,
Expand All @@ -125,6 +136,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'upca',
icon: barcodeIcon,
content: '416000336108',
position,
...defaultColors,
Expand All @@ -139,6 +151,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'upce',
icon: barcodeIcon,
content: '00123457',
position,
...defaultColors,
Expand All @@ -152,6 +165,7 @@ const barcodeDefaults: { defaultSchema: BarcodeSchema }[] = [
{
defaultSchema: {
type: 'gs1datamatrix',
icon: barcodeIcon,
content: '(01)03453120000011(17)191125(10)ABCD1234',
position,
...defaultColors,
Expand Down
2 changes: 2 additions & 0 deletions packages/schemas/src/graphics/image.ts
Expand Up @@ -181,6 +181,7 @@ const imageSchema: Plugin<ImageSchema> = {
schema: {},
defaultSchema: {
type: 'image',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-image"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>',
content: defaultValue,
position: { x: 0, y: 0 },
width: 40,
Expand All @@ -203,6 +204,7 @@ export const readOnlyImage: Plugin<ImageSchema> = {
defaultSchema: {
...imageSchema.propPanel.defaultSchema,
type: 'readOnlyImage',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-image-off"><line x1="2" x2="22" y1="2" y2="22"/><path d="M10.41 10.41a2 2 0 1 1-2.83-2.83"/><line x1="13.5" x2="6" y1="13.5" y2="21"/><line x1="18" x2="21" y1="12" y2="15"/><path d="M3.59 3.59A1.99 1.99 0 0 0 3 5v14a2 2 0 0 0 2 2h14c.55 0 1.052-.22 1.41-.59"/><path d="M21 15V5a2 2 0 0 0-2-2H9"/></svg>',
readOnly: true,
},
},
Expand Down
2 changes: 2 additions & 0 deletions packages/schemas/src/graphics/svg.ts
Expand Up @@ -73,6 +73,7 @@ const svgSchema: Plugin<SVGSchema> = {
schema: {},
defaultSchema: {
type: 'svg',
icon:'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-route"><circle cx="6" cy="19" r="3"/><path d="M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15"/><circle cx="18" cy="5" r="3"/></svg>',
content: defaultValue,
position: { x: 0, y: 0 },
width: 40,
Expand All @@ -91,6 +92,7 @@ export const readOnlySvg: Plugin<SVGSchema> = {
defaultSchema: {
...svgSchema.propPanel.defaultSchema,
type: 'readOnlySvg',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-route-off"><circle cx="6" cy="19" r="3"/><path d="M9 19h8.5c.4 0 .9-.1 1.3-.2"/><path d="M5.2 5.2A3.5 3.53 0 0 0 6.5 12H12"/><path d="m2 2 20 20"/><path d="M21 15.3a3.5 3.5 0 0 0-3.3-3.3"/><path d="M15 5h-4.3"/><circle cx="18" cy="5" r="3"/></svg>',
readOnly: true,
},
},
Expand Down
1 change: 1 addition & 0 deletions packages/schemas/src/shapes/line.ts
Expand Up @@ -50,6 +50,7 @@ const lineSchema: Plugin<LineSchema> = {
}),
defaultSchema: {
type: 'line',
icon:'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus"><path d="M5 12h14"/></svg>',
position: { x: 0, y: 0 },
width: 50,
height: 1,
Expand Down
15 changes: 12 additions & 3 deletions packages/schemas/src/shapes/rectAndEllipse.ts
Expand Up @@ -93,17 +93,26 @@ const shape: Plugin<ShapeSchema> = {
height: 37.5,
rotate: 0,
opacity: 1,
borderWidth: 5,
borderWidth: 1,
borderColor: '#000000',
color: '#ffffff',
color: '',
readOnly: true,
},
},
};

const rectangleIcon =
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square"><rect width="18" height="18" x="3" y="3" rx="2"/></svg>';
const ellipseIcon =
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle"><circle cx="12" cy="12" r="10"/></svg>';

const getPropPanelSchema = (type: 'rectangle' | 'ellipse') => ({
...shape.propPanel,
defaultSchema: { ...shape.propPanel.defaultSchema, type },
defaultSchema: {
...shape.propPanel.defaultSchema,
type,
icon: type === 'rectangle' ? rectangleIcon : ellipseIcon,
},
});

export const rectangle = { ...shape, propPanel: getPropPanelSchema('rectangle') };
Expand Down
1 change: 1 addition & 0 deletions packages/schemas/src/tables/propPanel.ts
Expand Up @@ -62,6 +62,7 @@ export const propPanel: PropPanel<TableSchema> = {
},
defaultSchema: {
type: 'table',
icon:'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-table"><path d="M12 3v18"/><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/></svg>',
position: { x: 0, y: 0 },
width: 150,
height: 20,
Expand Down
1 change: 1 addition & 0 deletions packages/schemas/src/text/index.ts
Expand Up @@ -16,6 +16,7 @@ export const readOnlyText: Plugin<TextSchema> = {
defaultSchema: {
...textSchema.propPanel.defaultSchema,
type: 'readOnlyText',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-type"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" x2="15" y1="20" y2="20"/><line x1="12" x2="12" y1="4" y2="20"/></svg>',
readOnly: true,
},
},
Expand Down
1 change: 1 addition & 0 deletions packages/schemas/src/text/propPanel.ts
Expand Up @@ -177,6 +177,7 @@ export const propPanel: PropPanel<TextSchema> = {
widgets: { UseDynamicFontSize },
defaultSchema: {
type: 'text',
icon: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-text-cursor-input"><path d="M5 4h1a3 3 0 0 1 3 3 3 3 0 0 1 3-3h1"/><path d="M13 20h-1a3 3 0 0 1-3-3 3 3 0 0 1-3 3H5"/><path d="M5 16H4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h1"/><path d="M13 8h7a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-7"/><path d="M9 7v10"/></svg>',
content: 'Type Something...',
position: { x: 0, y: 0 },
width: 45,
Expand Down
142 changes: 125 additions & 17 deletions packages/ui/__tests__/components/__snapshots__/Designer.test.tsx.snap
Expand Up @@ -91,6 +91,111 @@ exports[`Designer snapshot 1`] = `
</div>
</div>
</div>
<div
style="left: 0px; position: absolute; right: 0px; z-index: 1; height: 0px; background: rgb(245, 245, 245); text-align: center; width: 45px;"
>
<div
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="draggable"
role="button"
tabindex="0"
>
<div
style="visibility: visible;"
>
<button
class="ant-btn css-dev-only-do-not-override-gzal6t ant-btn-default"
style="width: 35px; height: 35px; margin-top: 0.25rem; padding: 0.25rem;"
title="text"
type="button"
>
<div>
<svg
class="lucide lucide-text-cursor-input"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5 4h1a3 3 0 0 1 3 3 3 3 0 0 1 3-3h1"
/>
<path
d="M13 20h-1a3 3 0 0 1-3-3 3 3 0 0 1-3 3H5"
/>
<path
d="M5 16H4a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h1"
/>
<path
d="M13 8h7a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-7"
/>
<path
d="M9 7v10"
/>
</svg>
</div>
</button>
</div>
</div>
<div
aria-describedby="DndDescribedBy-0"
aria-disabled="false"
aria-roledescription="draggable"
role="button"
tabindex="0"
>
<div
style="visibility: visible;"
>
<button
class="ant-btn css-dev-only-do-not-override-gzal6t ant-btn-default"
style="width: 35px; height: 35px; margin-top: 0.25rem; padding: 0.25rem;"
title="image"
type="button"
>
<div>
<svg
class="lucide lucide-image"
fill="none"
height="24"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<rect
height="18"
rx="2"
ry="2"
width="18"
x="3"
y="3"
/>
<circle
cx="9"
cy="9"
r="2"
/>
<path
d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"
/>
</svg>
</div>
</button>
</div>
</div>
</div>
<div
style="position: absolute; right: 0px; z-index: 1; height: 100%; width: 400px;"
>
Expand Down Expand Up @@ -148,7 +253,7 @@ exports[`Designer snapshot 1`] = `
style="margin-top: 8px; margin-bottom: 8px;"
/>
<div
style="height: 1000px;"
style="height: 1085px;"
>
<div
style="height: 100%; overflow-y: auto;"
Expand Down Expand Up @@ -251,7 +356,7 @@ exports[`Designer snapshot 1`] = `
</ul>
</div>
<div
id="DndDescribedBy-0"
id="DndDescribedBy-1"
style="display: none;"
>
Expand All @@ -268,7 +373,7 @@ exports[`Designer snapshot 1`] = `
style="position: fixed; width: 1px; height: 1px; margin: -1px; border: 0px; padding: 0px; overflow: hidden; clip-path: inset(100%); white-space: nowrap;"
/>
<div
style="display: flex; align-items: center; justify-content: flex-end; height: 40px; border-bottom: 1px solid rgba(5, 5, 5, 0.06);"
style="padding-top: 0.5rem; display: flex; align-items: center; justify-content: flex-end;"
>
<button
class="ant-btn css-dev-only-do-not-override-gzal6t ant-btn-text ant-btn-sm"
Expand All @@ -284,20 +389,6 @@ exports[`Designer snapshot 1`] = `
</div>
</div>
</div>
<div
style="position: absolute; bottom: 1.5rem; margin-top: 1rem; left: 50%; transform: translateX(-50%);"
>
<button
class="ant-btn css-dev-only-do-not-override-gzal6t ant-btn-primary"
style="font-weight: 600;"
type="button"
>
<span>
Add new field
</span>
</button>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -522,6 +613,23 @@ exports[`Designer snapshot 1`] = `
</div>
</div>
</div>
<div
id="DndDescribedBy-0"
style="display: none;"
>
To pick up a draggable item, press the space bar.
While dragging, use the arrow keys to move the item.
Press space again to drop the item in its new position, or press escape to cancel.
</div>
<div
aria-atomic="true"
aria-live="assertive"
id="DndLiveRegion-1"
role="status"
style="position: fixed; width: 1px; height: 1px; margin: -1px; border: 0px; padding: 0px; overflow: hidden; clip-path: inset(100%); white-space: nowrap;"
/>
</div>
</div>
`;

0 comments on commit 8ddfa7a

Please sign in to comment.