@expressive/ui 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +47 -1
  2. package/dist/button/base.d.ts +63 -0
  3. package/dist/button/base.js +90 -0
  4. package/dist/button/base.js.map +1 -0
  5. package/dist/button/button.d.ts +56 -0
  6. package/dist/button/button.js +138 -0
  7. package/dist/button/button.js.map +1 -0
  8. package/dist/calendar/base.d.ts +112 -0
  9. package/dist/calendar/base.js +235 -0
  10. package/dist/calendar/base.js.map +1 -0
  11. package/dist/calendar/calendar.d.ts +78 -0
  12. package/dist/calendar/calendar.js +145 -0
  13. package/dist/calendar/calendar.js.map +1 -0
  14. package/dist/calendar/date.js +56 -0
  15. package/dist/calendar/date.js.map +1 -0
  16. package/dist/dialog/base.d.ts +74 -0
  17. package/dist/dialog/base.js +143 -0
  18. package/dist/dialog/base.js.map +1 -0
  19. package/dist/dialog/dialog.d.ts +69 -0
  20. package/dist/dialog/dialog.js +108 -0
  21. package/dist/dialog/dialog.js.map +1 -0
  22. package/dist/dom.d.ts +16 -0
  23. package/dist/dom.js +17 -0
  24. package/dist/dropzone/base.d.ts +77 -0
  25. package/dist/dropzone/base.js +159 -0
  26. package/dist/dropzone/base.js.map +1 -0
  27. package/dist/dropzone/dropzone.d.ts +38 -0
  28. package/dist/dropzone/dropzone.js +92 -0
  29. package/dist/dropzone/dropzone.js.map +1 -0
  30. package/dist/form/base.d.ts +157 -0
  31. package/dist/form/base.js +243 -0
  32. package/dist/form/base.js.map +1 -0
  33. package/dist/form/form.d.ts +123 -0
  34. package/dist/form/form.js +179 -0
  35. package/dist/form/form.js.map +1 -0
  36. package/dist/icons/caret.d.ts +8 -0
  37. package/dist/icons/caret.js +16 -0
  38. package/dist/icons/caret.js.map +1 -0
  39. package/dist/icons/check.d.ts +8 -0
  40. package/dist/icons/check.js +16 -0
  41. package/dist/icons/check.js.map +1 -0
  42. package/dist/icons/cross.d.ts +8 -0
  43. package/dist/icons/cross.js +16 -0
  44. package/dist/icons/cross.js.map +1 -0
  45. package/dist/icons/icon.js +16 -0
  46. package/dist/icons/icon.js.map +1 -0
  47. package/dist/icons/spinner.d.ts +8 -0
  48. package/dist/icons/spinner.js +27 -0
  49. package/dist/icons/spinner.js.map +1 -0
  50. package/dist/icons/upload.d.ts +8 -0
  51. package/dist/icons/upload.js +16 -0
  52. package/dist/icons/upload.js.map +1 -0
  53. package/dist/index.d.ts +11 -0
  54. package/dist/index.js +12 -0
  55. package/dist/layout/base.d.ts +88 -0
  56. package/dist/layout/base.js +158 -0
  57. package/dist/layout/base.js.map +1 -0
  58. package/dist/layout/layout.d.ts +53 -0
  59. package/dist/layout/layout.js +80 -0
  60. package/dist/layout/layout.js.map +1 -0
  61. package/dist/piece.js +13 -0
  62. package/dist/piece.js.map +1 -0
  63. package/dist/popover/base.d.ts +94 -0
  64. package/dist/popover/base.js +176 -0
  65. package/dist/popover/base.js.map +1 -0
  66. package/dist/popover/place.d.ts +12 -0
  67. package/dist/popover/place.js +32 -0
  68. package/dist/popover/place.js.map +1 -0
  69. package/dist/popover/popover.d.ts +52 -0
  70. package/dist/popover/popover.js +104 -0
  71. package/dist/popover/popover.js.map +1 -0
  72. package/dist/select/base.d.ts +196 -0
  73. package/dist/select/base.js +409 -0
  74. package/dist/select/base.js.map +1 -0
  75. package/dist/select/select.d.ts +119 -0
  76. package/dist/select/select.js +219 -0
  77. package/dist/select/select.js.map +1 -0
  78. package/dist/table/base.d.ts +96 -0
  79. package/dist/table/base.js +154 -0
  80. package/dist/table/base.js.map +1 -0
  81. package/dist/table/column.d.ts +53 -0
  82. package/dist/table/column.js +29 -0
  83. package/dist/table/column.js.map +1 -0
  84. package/dist/table/table.d.ts +41 -0
  85. package/dist/table/table.js +101 -0
  86. package/dist/table/table.js.map +1 -0
  87. package/package.json +68 -3
@@ -0,0 +1,123 @@
1
+ import { Button } from "../button/button.js";
2
+ import { Field as Field$1, Form as Form$1, Submit as Submit$1 } from "./base.js";
3
+ import { Component } from "@expressive/mvc";
4
+
5
+ //#region src/form/form.d.ts
6
+ declare namespace Form {
7
+ type Values<T extends Form$1> = Form$1.Values<T>;
8
+ type Check = Form$1.Check;
9
+ }
10
+ /**
11
+ * Form whose values are the fields a subclass declares, edited through `Field` children.
12
+ *
13
+ * Submitting checks every field, focuses the first that fails, and otherwise passes `values()` to `onSubmit` -
14
+ * or to `submit()` in a subclass. `pending` holds while that runs; a throw lands on `error` and shows below the
15
+ * fields. Pieces - `Root`, `Failure` - are function components reading `Form.get()`, each styled on its own; pass
16
+ * one as a prop or assign it in a subclass to replace it. Stock pieces are statics.
17
+ *
18
+ * @example
19
+ * class Signup extends Form {
20
+ * email = '';
21
+ * password = '';
22
+ * }
23
+ *
24
+ * <Signup onSubmit={(values) => api.signup(values)}>
25
+ * <Field name="email" type="email" />
26
+ * <Field name="password" type="password" validate={(value) => value.length >= 8 || 'At least 8 characters'} />
27
+ * <Submit>Sign up</Submit>
28
+ * </Signup>
29
+ */
30
+ declare class Form extends Form$1 {
31
+ static Root: ({
32
+ children
33
+ }: {
34
+ children?: Component.Node;
35
+ }) => Component.Node;
36
+ static Failure: ({
37
+ error
38
+ }: {
39
+ error: Error;
40
+ }) => Component.Node;
41
+ Root: ({
42
+ children
43
+ }: {
44
+ children?: Component.Node;
45
+ }) => Component.Node;
46
+ Failure: ({
47
+ error
48
+ }: {
49
+ error: Error;
50
+ }) => Component.Node;
51
+ }
52
+ /**
53
+ * Labelled input bound to the enclosing `Form`'s field `name`.
54
+ *
55
+ * Required unless `optional`. `validate` returns `false` or a message to fail. A failed field rechecks as it
56
+ * changes. The input's type follows `type`; `multiline` renders a textarea, and a number field writes numbers.
57
+ * Pieces - `Root`, `Label`, `Control`, `Message` - are function components reading `Field.get()`, each styled on
58
+ * its own; a replacement `Control` binds another control by calling `update(value)`. Stock pieces are statics.
59
+ *
60
+ * @example
61
+ * <Field name="email" type="email" hint="We never share it." />
62
+ */
63
+ declare class Field<T = any> extends Field$1<T> {
64
+ static Root: ({
65
+ children
66
+ }: {
67
+ children?: Component.Node;
68
+ }) => Component.Node;
69
+ static Label: () => Component.Node;
70
+ static Control: () => Component.Node;
71
+ static Message: () => Component.Node;
72
+ Root: ({
73
+ children
74
+ }: {
75
+ children?: Component.Node;
76
+ }) => Component.Node;
77
+ Label: () => Component.Node;
78
+ Control: () => Component.Node;
79
+ Message: () => Component.Node;
80
+ }
81
+ /**
82
+ * Submit button for the enclosing `Form`; shows pending while it submits.
83
+ *
84
+ * Pieces - `Root`, `Label`, `Status` - are `Button`'s.
85
+ *
86
+ * @example
87
+ * <Submit>Save</Submit>
88
+ */
89
+ declare class Submit extends Submit$1 {
90
+ static Root: ({
91
+ children
92
+ }: {
93
+ children?: Component.Node;
94
+ }) => Component.Node;
95
+ static Label: ({
96
+ children
97
+ }: {
98
+ children?: Component.Node;
99
+ }) => Component.Node;
100
+ static Status: ({
101
+ status
102
+ }: {
103
+ status: Button.Status;
104
+ }) => Component.Node;
105
+ Root: ({
106
+ children
107
+ }: {
108
+ children?: Component.Node;
109
+ }) => Component.Node;
110
+ Label: ({
111
+ children
112
+ }: {
113
+ children?: Component.Node;
114
+ }) => Component.Node;
115
+ Status: ({
116
+ status
117
+ }: {
118
+ status: Button.Status;
119
+ }) => Component.Node;
120
+ }
121
+ //#endregion
122
+ export { Field, Form, Submit };
123
+ //# sourceMappingURL=form.d.ts.map
@@ -0,0 +1,179 @@
1
+ import { Field as Field$1, Form as Form$1, Submit as Submit$1 } from "./base.js";
2
+ import { Button } from "../button/button.js";
3
+ import { style } from "@expressive/dom";
4
+ import { jsx, jsxs } from "@expressive/dom/jsx-runtime";
5
+
6
+ //#region src/form/form.tsx
7
+ const Root = ({ children }) => /* @__PURE__ */ jsx("form", {
8
+ ...Form$1.get().formProps,
9
+ children
10
+ });
11
+ style(Root, {
12
+ display: "flex",
13
+ flexDirection: "column",
14
+ alignItems: "stretch",
15
+ gap: "16px"
16
+ });
17
+ const Failure = ({ error }) => /* @__PURE__ */ jsx("p", {
18
+ role: "alert",
19
+ children: error.message
20
+ });
21
+ style(Failure, {
22
+ margin: "0",
23
+ color: "var(--ui-danger, #e5484d)"
24
+ });
25
+ /**
26
+ * Form whose values are the fields a subclass declares, edited through `Field` children.
27
+ *
28
+ * Submitting checks every field, focuses the first that fails, and otherwise passes `values()` to `onSubmit` -
29
+ * or to `submit()` in a subclass. `pending` holds while that runs; a throw lands on `error` and shows below the
30
+ * fields. Pieces - `Root`, `Failure` - are function components reading `Form.get()`, each styled on its own; pass
31
+ * one as a prop or assign it in a subclass to replace it. Stock pieces are statics.
32
+ *
33
+ * @example
34
+ * class Signup extends Form {
35
+ * email = '';
36
+ * password = '';
37
+ * }
38
+ *
39
+ * <Signup onSubmit={(values) => api.signup(values)}>
40
+ * <Field name="email" type="email" />
41
+ * <Field name="password" type="password" validate={(value) => value.length >= 8 || 'At least 8 characters'} />
42
+ * <Submit>Sign up</Submit>
43
+ * </Signup>
44
+ */
45
+ var Form = class extends Form$1 {
46
+ static Root = Root;
47
+ static Failure = Failure;
48
+ Root = Root;
49
+ Failure = Failure;
50
+ };
51
+ const Group = ({ children }) => /* @__PURE__ */ jsx("div", {
52
+ _check: Field$1.get().type == "checkbox",
53
+ children
54
+ });
55
+ style(Group, {
56
+ display: "flex",
57
+ flexDirection: "column",
58
+ gap: "6px",
59
+ _check: {
60
+ flexDirection: "row",
61
+ flexWrap: "wrap",
62
+ alignItems: "center",
63
+ gap: "8px"
64
+ }
65
+ });
66
+ const Label = () => {
67
+ const { optional, labelProps } = Field$1.get();
68
+ return /* @__PURE__ */ jsxs("label", {
69
+ ...labelProps.props,
70
+ children: [labelProps.text, optional && /* @__PURE__ */ jsx("span", {
71
+ _optional: true,
72
+ children: " (optional)"
73
+ })]
74
+ });
75
+ };
76
+ style(Label, {
77
+ fontWeight: "500",
78
+ _optional: {
79
+ color: "var(--ui-muted, #999)",
80
+ fontWeight: "400"
81
+ }
82
+ });
83
+ const box = {
84
+ boxSizing: "border-box",
85
+ width: "100%",
86
+ padding: "8px 10px",
87
+ border: "1px solid var(--ui-line, #ccc)",
88
+ borderRadius: "4px",
89
+ background: "var(--ui-surface, #fff)",
90
+ color: "inherit",
91
+ font: "inherit",
92
+ outline: "0",
93
+ transition: "border-color 100ms, box-shadow 100ms",
94
+ ":focus": {
95
+ borderColor: "var(--ui-accent, #2684ff)",
96
+ boxShadow: "0 0 0 1px var(--ui-accent, #2684ff)"
97
+ },
98
+ ":disabled": { opacity: "0.6" }
99
+ };
100
+ const Control = () => {
101
+ const { type, multiline, controlProps } = Field$1.get();
102
+ const { failed, props } = controlProps;
103
+ if (type == "checkbox") return /* @__PURE__ */ jsx("input", { ...props });
104
+ if (multiline) return /* @__PURE__ */ jsx("textarea", {
105
+ ...props,
106
+ _text: true,
107
+ _failed: failed
108
+ });
109
+ return /* @__PURE__ */ jsx("input", {
110
+ ...props,
111
+ _text: true,
112
+ _failed: failed
113
+ });
114
+ };
115
+ style(Control, {
116
+ _text: box,
117
+ _textarea: {
118
+ minHeight: "80px",
119
+ resize: "vertical"
120
+ },
121
+ _failed: { borderColor: "var(--ui-danger, #e5484d)" }
122
+ });
123
+ const Message = () => {
124
+ const { text, failed, props } = Field$1.get().messageProps;
125
+ return /* @__PURE__ */ jsx("p", {
126
+ ...props,
127
+ _failed: failed,
128
+ children: text
129
+ });
130
+ };
131
+ style(Message, {
132
+ flexBasis: "100%",
133
+ margin: "0",
134
+ color: "var(--ui-muted, #999)",
135
+ fontSize: "13px",
136
+ _failed: { color: "var(--ui-danger, #e5484d)" }
137
+ });
138
+ /**
139
+ * Labelled input bound to the enclosing `Form`'s field `name`.
140
+ *
141
+ * Required unless `optional`. `validate` returns `false` or a message to fail. A failed field rechecks as it
142
+ * changes. The input's type follows `type`; `multiline` renders a textarea, and a number field writes numbers.
143
+ * Pieces - `Root`, `Label`, `Control`, `Message` - are function components reading `Field.get()`, each styled on
144
+ * its own; a replacement `Control` binds another control by calling `update(value)`. Stock pieces are statics.
145
+ *
146
+ * @example
147
+ * <Field name="email" type="email" hint="We never share it." />
148
+ */
149
+ var Field = class extends Field$1 {
150
+ static Root = Group;
151
+ static Label = Label;
152
+ static Control = Control;
153
+ static Message = Message;
154
+ Root = Group;
155
+ Label = Label;
156
+ Control = Control;
157
+ Message = Message;
158
+ };
159
+ /**
160
+ * Submit button for the enclosing `Form`; shows pending while it submits.
161
+ *
162
+ * Pieces - `Root`, `Label`, `Status` - are `Button`'s.
163
+ *
164
+ * @example
165
+ * <Submit>Save</Submit>
166
+ */
167
+ var Submit = class extends Submit$1 {
168
+ static Root = Button.Root;
169
+ static Label = Button.Label;
170
+ static Status = Button.Status;
171
+ Root = Button.Root;
172
+ Label = Button.Label;
173
+ Status = Button.Status;
174
+ };
175
+ style(Submit, { alignSelf: "flex-start" });
176
+
177
+ //#endregion
178
+ export { Field, Form, Submit };
179
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.js","names":["Base.Form","Base.Field","Base.Submit"],"sources":["../../src/form/form.tsx"],"sourcesContent":["/** @jsxImportSource @expressive/dom */\nimport { Component } from '@expressive/mvc';\nimport { style } from '@expressive/dom';\n\nimport { Button } from '../button/button';\nimport * as Base from './base';\n\ndeclare namespace Form {\n type Values<T extends Base.Form> = Base.Form.Values<T>;\n type Check = Base.Form.Check;\n}\n\nconst Root = ({ children }: { children?: Component.Node }): Component.Node => (\n <form {...Base.Form.get().formProps}>{children}</form>\n);\n\nstyle(Root, {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'stretch',\n gap: '16px'\n});\n\nconst Failure = ({ error }: { error: Error }): Component.Node => (\n <p role=\"alert\">{error.message}</p>\n);\n\nstyle(Failure, {\n margin: '0',\n color: 'var(--ui-danger, #e5484d)'\n});\n\n/**\n * Form whose values are the fields a subclass declares, edited through `Field` children.\n *\n * Submitting checks every field, focuses the first that fails, and otherwise passes `values()` to `onSubmit` -\n * or to `submit()` in a subclass. `pending` holds while that runs; a throw lands on `error` and shows below the\n * fields. Pieces - `Root`, `Failure` - are function components reading `Form.get()`, each styled on its own; pass\n * one as a prop or assign it in a subclass to replace it. Stock pieces are statics.\n *\n * @example\n * class Signup extends Form {\n * email = '';\n * password = '';\n * }\n *\n * <Signup onSubmit={(values) => api.signup(values)}>\n * <Field name=\"email\" type=\"email\" />\n * <Field name=\"password\" type=\"password\" validate={(value) => value.length >= 8 || 'At least 8 characters'} />\n * <Submit>Sign up</Submit>\n * </Signup>\n */\nclass Form extends Base.Form {\n static Root = Root;\n static Failure = Failure;\n\n Root = Root;\n Failure = Failure;\n}\n\nconst Group = ({ children }: { children?: Component.Node }): Component.Node => (\n <div _check={Base.Field.get().type == 'checkbox'}>{children}</div>\n);\n\nstyle(Group, {\n display: 'flex',\n flexDirection: 'column',\n gap: '6px',\n _check: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '8px'\n }\n});\n\nconst Label = (): Component.Node => {\n const { optional, labelProps } = Base.Field.get();\n\n return (\n <label {...labelProps.props}>\n {labelProps.text}\n {optional && <span _optional> (optional)</span>}\n </label>\n );\n};\n\nstyle(Label, {\n fontWeight: '500',\n _optional: {\n color: 'var(--ui-muted, #999)',\n fontWeight: '400'\n }\n});\n\nconst box = {\n boxSizing: 'border-box',\n width: '100%',\n padding: '8px 10px',\n border: '1px solid var(--ui-line, #ccc)',\n borderRadius: '4px',\n background: 'var(--ui-surface, #fff)',\n color: 'inherit',\n font: 'inherit',\n outline: '0',\n transition: 'border-color 100ms, box-shadow 100ms',\n ':focus': {\n borderColor: 'var(--ui-accent, #2684ff)',\n boxShadow: '0 0 0 1px var(--ui-accent, #2684ff)'\n },\n ':disabled': {\n opacity: '0.6'\n }\n};\n\nconst Control = (): Component.Node => {\n const { type, multiline, controlProps } = Base.Field.get();\n const { failed, props } = controlProps;\n\n if (type == 'checkbox') return <input {...props} />;\n\n if (multiline) return <textarea {...props} _text _failed={failed} />;\n\n return <input {...props} _text _failed={failed} />;\n};\n\nstyle(Control, {\n _text: box,\n _textarea: {\n minHeight: '80px',\n resize: 'vertical'\n },\n _failed: {\n borderColor: 'var(--ui-danger, #e5484d)'\n }\n});\n\nconst Message = (): Component.Node => {\n const { text, failed, props } = Base.Field.get().messageProps;\n\n return (\n <p {...props} _failed={failed}>\n {text}\n </p>\n );\n};\n\nstyle(Message, {\n flexBasis: '100%',\n margin: '0',\n color: 'var(--ui-muted, #999)',\n fontSize: '13px',\n _failed: {\n color: 'var(--ui-danger, #e5484d)'\n }\n});\n\n/**\n * Labelled input bound to the enclosing `Form`'s field `name`.\n *\n * Required unless `optional`. `validate` returns `false` or a message to fail. A failed field rechecks as it\n * changes. The input's type follows `type`; `multiline` renders a textarea, and a number field writes numbers.\n * Pieces - `Root`, `Label`, `Control`, `Message` - are function components reading `Field.get()`, each styled on\n * its own; a replacement `Control` binds another control by calling `update(value)`. Stock pieces are statics.\n *\n * @example\n * <Field name=\"email\" type=\"email\" hint=\"We never share it.\" />\n */\nclass Field<T = any> extends Base.Field<T> {\n static Root = Group;\n static Label = Label;\n static Control = Control;\n static Message = Message;\n\n Root = Group;\n Label = Label;\n Control = Control;\n Message = Message;\n}\n\n/**\n * Submit button for the enclosing `Form`; shows pending while it submits.\n *\n * Pieces - `Root`, `Label`, `Status` - are `Button`'s.\n *\n * @example\n * <Submit>Save</Submit>\n */\nclass Submit extends Base.Submit {\n static Root = Button.Root;\n static Label = Button.Label;\n static Status = Button.Status;\n\n Root = Button.Root;\n Label = Button.Label;\n Status = Button.Status;\n}\n\nstyle(Submit, {\n alignSelf: 'flex-start'\n});\n\nexport { Control, Failure, Field, Form, Group, Label, Message, Root, Submit };\n"],"mappings":";;;;;;AAYA,MAAM,QAAQ,EAAE,eACd,oBAAC;CAAK,UAAc,KAAK,CAAC;CAAY;EAAgB;AAGxD,MAAM,MAAM;CACV,SAAS;CACT,eAAe;CACf,YAAY;CACZ,KAAK;CACN,CAAC;AAEF,MAAM,WAAW,EAAE,YACjB,oBAAC;CAAE,MAAK;WAAS,MAAM;EAAY;AAGrC,MAAM,SAAS;CACb,QAAQ;CACR,OAAO;CACR,CAAC;;;;;;;;;;;;;;;;;;;;;AAsBF,IAAM,OAAN,cAAmBA,OAAU;CAC3B,OAAO,OAAO;CACd,OAAO,UAAU;CAEjB,OAAO;CACP,UAAU;;AAGZ,MAAM,SAAS,EAAE,eACf,oBAAC;CAAI,gBAAmB,KAAK,CAAC,QAAQ;CAAa;EAAe;AAGpE,MAAM,OAAO;CACX,SAAS;CACT,eAAe;CACf,KAAK;CACL,QAAQ;EACN,eAAe;EACf,UAAU;EACV,YAAY;EACZ,KAAK;EACN;CACF,CAAC;AAEF,MAAM,cAA8B;CAClC,MAAM,EAAE,UAAU,uBAA0B,KAAK;AAEjD,QACE,qBAAC;EAAM,GAAI,WAAW;aACnB,WAAW,MACX,YAAY,oBAAC;GAAK;aAAU;IAAkB;GACzC;;AAIZ,MAAM,OAAO;CACX,YAAY;CACZ,WAAW;EACT,OAAO;EACP,YAAY;EACb;CACF,CAAC;AAEF,MAAM,MAAM;CACV,WAAW;CACX,OAAO;CACP,SAAS;CACT,QAAQ;CACR,cAAc;CACd,YAAY;CACZ,OAAO;CACP,MAAM;CACN,SAAS;CACT,YAAY;CACZ,UAAU;EACR,aAAa;EACb,WAAW;EACZ;CACD,aAAa,EACX,SAAS,OACV;CACF;AAED,MAAM,gBAAgC;CACpC,MAAM,EAAE,MAAM,WAAW,yBAA4B,KAAK;CAC1D,MAAM,EAAE,QAAQ,UAAU;AAE1B,KAAI,QAAQ,WAAY,QAAO,oBAAC,WAAM,GAAI,QAAS;AAEnD,KAAI,UAAW,QAAO,oBAAC;EAAS,GAAI;EAAO;EAAM,SAAS;GAAU;AAEpE,QAAO,oBAAC;EAAM,GAAI;EAAO;EAAM,SAAS;GAAU;;AAGpD,MAAM,SAAS;CACb,OAAO;CACP,WAAW;EACT,WAAW;EACX,QAAQ;EACT;CACD,SAAS,EACP,aAAa,6BACd;CACF,CAAC;AAEF,MAAM,gBAAgC;CACpC,MAAM,EAAE,MAAM,QAAQ,kBAAqB,KAAK,CAAC;AAEjD,QACE,oBAAC;EAAE,GAAI;EAAO,SAAS;YACpB;GACC;;AAIR,MAAM,SAAS;CACb,WAAW;CACX,QAAQ;CACR,OAAO;CACP,UAAU;CACV,SAAS,EACP,OAAO,6BACR;CACF,CAAC;;;;;;;;;;;;AAaF,IAAM,QAAN,cAA6BC,QAAc;CACzC,OAAO,OAAO;CACd,OAAO,QAAQ;CACf,OAAO,UAAU;CACjB,OAAO,UAAU;CAEjB,OAAO;CACP,QAAQ;CACR,UAAU;CACV,UAAU;;;;;;;;;;AAWZ,IAAM,SAAN,cAAqBC,SAAY;CAC/B,OAAO,OAAO,OAAO;CACrB,OAAO,QAAQ,OAAO;CACtB,OAAO,SAAS,OAAO;CAEvB,OAAO,OAAO;CACd,QAAQ,OAAO;CACf,SAAS,OAAO;;AAGlB,MAAM,QAAQ,EACZ,WAAW,cACZ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Component } from "@expressive/mvc";
2
+
3
+ //#region src/icons/caret.d.ts
4
+ /** Downward caret for a dropdown; inherits `currentColor`. */
5
+ declare const Caret: () => Component.Node;
6
+ //#endregion
7
+ export { Caret };
8
+ //# sourceMappingURL=caret.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { icon } from "./icon.js";
2
+ import { style } from "@expressive/dom";
3
+ import { jsx } from "@expressive/dom/jsx-runtime";
4
+
5
+ //#region src/icons/caret.tsx
6
+ /** Downward caret for a dropdown; inherits `currentColor`. */
7
+ const Caret = () => /* @__PURE__ */ jsx("svg", {
8
+ viewBox: "0 0 16 16",
9
+ "aria-hidden": "true",
10
+ children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" })
11
+ });
12
+ style(Caret, icon, { transition: "transform 150ms" });
13
+
14
+ //#endregion
15
+ export { Caret };
16
+ //# sourceMappingURL=caret.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caret.js","names":[],"sources":["../../src/icons/caret.tsx"],"sourcesContent":["/** @jsxImportSource @expressive/dom */\nimport type { Component } from '@expressive/mvc';\nimport { style } from '@expressive/dom';\n\nimport { icon } from './icon';\n\n/** Downward caret for a dropdown; inherits `currentColor`. */\nconst Caret = (): Component.Node => (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M4 6l4 4 4-4\" />\n </svg>\n);\n\nstyle(Caret, icon, { transition: 'transform 150ms' });\n\nexport { Caret };\n"],"mappings":";;;;;;AAOA,MAAM,cACJ,oBAAC;CAAI,SAAQ;CAAY,eAAY;WACnC,oBAAC,UAAK,GAAE,iBAAiB;EACrB;AAGR,MAAM,OAAO,MAAM,EAAE,YAAY,mBAAmB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Component } from "@expressive/mvc";
2
+
3
+ //#region src/icons/check.d.ts
4
+ /** Check mark for success; inherits `currentColor`. */
5
+ declare const Check: () => Component.Node;
6
+ //#endregion
7
+ export { Check };
8
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { icon } from "./icon.js";
2
+ import { style } from "@expressive/dom";
3
+ import { jsx } from "@expressive/dom/jsx-runtime";
4
+
5
+ //#region src/icons/check.tsx
6
+ /** Check mark for success; inherits `currentColor`. */
7
+ const Check = () => /* @__PURE__ */ jsx("svg", {
8
+ viewBox: "0 0 16 16",
9
+ "aria-hidden": "true",
10
+ children: /* @__PURE__ */ jsx("path", { d: "M3.5 8.5l3 3 6-7" })
11
+ });
12
+ style(Check, icon);
13
+
14
+ //#endregion
15
+ export { Check };
16
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","names":[],"sources":["../../src/icons/check.tsx"],"sourcesContent":["/** @jsxImportSource @expressive/dom */\nimport type { Component } from '@expressive/mvc';\nimport { style } from '@expressive/dom';\n\nimport { icon } from './icon';\n\n/** Check mark for success; inherits `currentColor`. */\nconst Check = (): Component.Node => (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M3.5 8.5l3 3 6-7\" />\n </svg>\n);\n\nstyle(Check, icon);\n\nexport { Check };\n"],"mappings":";;;;;;AAOA,MAAM,cACJ,oBAAC;CAAI,SAAQ;CAAY,eAAY;WACnC,oBAAC,UAAK,GAAE,qBAAqB;EACzB;AAGR,MAAM,OAAO,KAAK"}
@@ -0,0 +1,8 @@
1
+ import { Component } from "@expressive/mvc";
2
+
3
+ //#region src/icons/cross.d.ts
4
+ /** Cross for clear and remove buttons; inherits `currentColor`. */
5
+ declare const Cross: () => Component.Node;
6
+ //#endregion
7
+ export { Cross };
8
+ //# sourceMappingURL=cross.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { icon } from "./icon.js";
2
+ import { style } from "@expressive/dom";
3
+ import { jsx } from "@expressive/dom/jsx-runtime";
4
+
5
+ //#region src/icons/cross.tsx
6
+ /** Cross for clear and remove buttons; inherits `currentColor`. */
7
+ const Cross = () => /* @__PURE__ */ jsx("svg", {
8
+ viewBox: "0 0 16 16",
9
+ "aria-hidden": "true",
10
+ children: /* @__PURE__ */ jsx("path", { d: "M4 4l8 8M12 4l-8 8" })
11
+ });
12
+ style(Cross, icon);
13
+
14
+ //#endregion
15
+ export { Cross };
16
+ //# sourceMappingURL=cross.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross.js","names":[],"sources":["../../src/icons/cross.tsx"],"sourcesContent":["/** @jsxImportSource @expressive/dom */\nimport type { Component } from '@expressive/mvc';\nimport { style } from '@expressive/dom';\n\nimport { icon } from './icon';\n\n/** Cross for clear and remove buttons; inherits `currentColor`. */\nconst Cross = (): Component.Node => (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M4 4l8 8M12 4l-8 8\" />\n </svg>\n);\n\nstyle(Cross, icon);\n\nexport { Cross };\n"],"mappings":";;;;;;AAOA,MAAM,cACJ,oBAAC;CAAI,SAAQ;CAAY,eAAY;WACnC,oBAAC,UAAK,GAAE,uBAAuB;EAC3B;AAGR,MAAM,OAAO,KAAK"}
@@ -0,0 +1,16 @@
1
+ //#region src/icons/icon.ts
2
+ const icon = {
3
+ display: "block",
4
+ flexShrink: "0",
5
+ width: "16px",
6
+ height: "16px",
7
+ fill: "none",
8
+ stroke: "currentColor",
9
+ strokeWidth: "1.75",
10
+ strokeLinecap: "round",
11
+ strokeLinejoin: "round"
12
+ };
13
+
14
+ //#endregion
15
+ export { icon };
16
+ //# sourceMappingURL=icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon.js","names":[],"sources":["../../src/icons/icon.ts"],"sourcesContent":["export const icon = {\n display: 'block',\n flexShrink: '0',\n width: '16px',\n height: '16px',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: '1.75',\n strokeLinecap: 'round',\n strokeLinejoin: 'round'\n};\n"],"mappings":";AAAA,MAAa,OAAO;CAClB,SAAS;CACT,YAAY;CACZ,OAAO;CACP,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,aAAa;CACb,eAAe;CACf,gBAAgB;CACjB"}
@@ -0,0 +1,8 @@
1
+ import { Component } from "@expressive/mvc";
2
+
3
+ //#region src/icons/spinner.d.ts
4
+ /** Spinning arc for pending work; inherits `currentColor`. */
5
+ declare const Spinner: () => Component.Node;
6
+ //#endregion
7
+ export { Spinner };
8
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { icon } from "./icon.js";
2
+ import { style } from "@expressive/dom";
3
+ import { jsx } from "@expressive/dom/jsx-runtime";
4
+
5
+ //#region src/icons/spinner.tsx
6
+ /** Spinning arc for pending work; inherits `currentColor`. */
7
+ const Spinner = () => /* @__PURE__ */ jsx("svg", {
8
+ viewBox: "0 0 16 16",
9
+ "aria-hidden": "true",
10
+ children: /* @__PURE__ */ jsx("path", {
11
+ d: "M8 2a6 6 0 1 1-6 6",
12
+ children: /* @__PURE__ */ jsx("animateTransform", { ...spin })
13
+ })
14
+ });
15
+ style(Spinner, icon);
16
+ const spin = {
17
+ attributeName: "transform",
18
+ type: "rotate",
19
+ from: "0 8 8",
20
+ to: "360 8 8",
21
+ dur: "0.8s",
22
+ repeatCount: "indefinite"
23
+ };
24
+
25
+ //#endregion
26
+ export { Spinner };
27
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","names":[],"sources":["../../src/icons/spinner.tsx"],"sourcesContent":["/** @jsxImportSource @expressive/dom */\nimport type { Component } from '@expressive/mvc';\nimport { style } from '@expressive/dom';\n\nimport { icon } from './icon';\n\n/** Spinning arc for pending work; inherits `currentColor`. */\nconst Spinner = (): Component.Node => (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M8 2a6 6 0 1 1-6 6\">\n <animateTransform {...spin} />\n </path>\n </svg>\n);\n\nstyle(Spinner, icon);\n\nconst spin: {} = {\n attributeName: 'transform',\n type: 'rotate',\n from: '0 8 8',\n to: '360 8 8',\n dur: '0.8s',\n repeatCount: 'indefinite'\n};\n\nexport { Spinner };\n"],"mappings":";;;;;;AAOA,MAAM,gBACJ,oBAAC;CAAI,SAAQ;CAAY,eAAY;WACnC,oBAAC;EAAK,GAAE;YACN,oBAAC,sBAAiB,GAAI,OAAQ;GACzB;EACH;AAGR,MAAM,SAAS,KAAK;AAEpB,MAAM,OAAW;CACf,eAAe;CACf,MAAM;CACN,MAAM;CACN,IAAI;CACJ,KAAK;CACL,aAAa;CACd"}
@@ -0,0 +1,8 @@
1
+ import { Component } from "@expressive/mvc";
2
+
3
+ //#region src/icons/upload.d.ts
4
+ /** Upward arrow into a tray, for uploads; inherits `currentColor`. */
5
+ declare const Upload: () => Component.Node;
6
+ //#endregion
7
+ export { Upload };
8
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { icon } from "./icon.js";
2
+ import { style } from "@expressive/dom";
3
+ import { jsx } from "@expressive/dom/jsx-runtime";
4
+
5
+ //#region src/icons/upload.tsx
6
+ /** Upward arrow into a tray, for uploads; inherits `currentColor`. */
7
+ const Upload = () => /* @__PURE__ */ jsx("svg", {
8
+ viewBox: "0 0 16 16",
9
+ "aria-hidden": "true",
10
+ children: /* @__PURE__ */ jsx("path", { d: "M8 10V2.5M4.5 6L8 2.5 11.5 6M2.5 10v2.5a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1V10" })
11
+ });
12
+ style(Upload, icon);
13
+
14
+ //#endregion
15
+ export { Upload };
16
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","names":[],"sources":["../../src/icons/upload.tsx"],"sourcesContent":["/** @jsxImportSource @expressive/dom */\nimport type { Component } from '@expressive/mvc';\nimport { style } from '@expressive/dom';\n\nimport { icon } from './icon';\n\n/** Upward arrow into a tray, for uploads; inherits `currentColor`. */\nconst Upload = (): Component.Node => (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path d=\"M8 10V2.5M4.5 6L8 2.5 11.5 6M2.5 10v2.5a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1V10\" />\n </svg>\n);\n\nstyle(Upload, icon);\n\nexport { Upload };\n"],"mappings":";;;;;;AAOA,MAAM,eACJ,oBAAC;CAAI,SAAQ;CAAY,eAAY;WACnC,oBAAC,UAAK,GAAE,6EAA6E;EACjF;AAGR,MAAM,QAAQ,KAAK"}
@@ -0,0 +1,11 @@
1
+ import { Button } from "./button/base.js";
2
+ import { Calendar } from "./calendar/base.js";
3
+ import { Dialog } from "./dialog/base.js";
4
+ import { Dropzone } from "./dropzone/base.js";
5
+ import { Field, Form, Submit } from "./form/base.js";
6
+ import { Layout } from "./layout/base.js";
7
+ import { Popover } from "./popover/base.js";
8
+ import { Select } from "./select/base.js";
9
+ import { CellProps, CellSlot, Column, HeadProps, HeadSlot } from "./table/column.js";
10
+ import { Table } from "./table/base.js";
11
+ export { Button, Calendar, type CellProps, type CellSlot, Column, Dialog, Dropzone, Field, Form, type HeadProps, type HeadSlot, Layout, Popover, Select, Submit, Table };
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { Button } from "./button/base.js";
2
+ import { Calendar } from "./calendar/base.js";
3
+ import { Dialog } from "./dialog/base.js";
4
+ import { Dropzone } from "./dropzone/base.js";
5
+ import { Field, Form, Submit } from "./form/base.js";
6
+ import { Layout } from "./layout/base.js";
7
+ import { Popover } from "./popover/base.js";
8
+ import { Select } from "./select/base.js";
9
+ import { Column } from "./table/column.js";
10
+ import { Table } from "./table/base.js";
11
+
12
+ export { Button, Calendar, Column, Dialog, Dropzone, Field, Form, Layout, Popover, Select, Submit, Table };
@@ -0,0 +1,88 @@
1
+ import { Component, Model } from "@expressive/mvc";
2
+
3
+ //#region src/layout/base.d.ts
4
+ declare namespace Layout {
5
+ type Direction = 'row' | 'column';
6
+ interface HandleProps {
7
+ /** Index of the pane before this handle. */
8
+ index: number;
9
+ /** True while this handle is being dragged. */
10
+ active: boolean;
11
+ }
12
+ type Key = Pick<KeyboardEvent, 'key' | 'preventDefault'>;
13
+ type Point = Pick<PointerEvent, 'clientX' | 'clientY'>;
14
+ type Pointer = Point & Pick<PointerEvent, 'button' | 'preventDefault'>;
15
+ type Style = Record<string, string>;
16
+ type Root = (props: {
17
+ children: Component.Node;
18
+ }) => Component.Node;
19
+ type Handle = (props: HandleProps) => Component.Node;
20
+ }
21
+ /**
22
+ * Resizable panes without a look: weights, pointer and keyboard resizing and ARIA, assembled from pieces.
23
+ *
24
+ * `Root` wraps the panes and spreads `rootProps`, styled by `arrange`. `Handle` sits between neighbors and spreads
25
+ * `handleProps(index)`. Both are placeholders that throw when rendered, and `arrange` throws when called - a skin
26
+ * supplies all three.
27
+ */
28
+ declare class Layout extends Component {
29
+ /** `row` puts panes side by side. Defaults to across the parent `Layout`, else `row`. */
30
+ direction?: Layout.Direction;
31
+ /** Initial weights per pane; read until the first resize, or when the pane count changes. */
32
+ sizes?: readonly number[];
33
+ /** Handle thickness in pixels. */
34
+ gap: number;
35
+ /** Smallest a pane can be dragged, in pixels. */
36
+ min: number;
37
+ /** Weights after a resize. */
38
+ weights: number[];
39
+ /** Index of the handle being dragged. */
40
+ dragging?: number;
41
+ Root: Layout.Root;
42
+ Handle: Layout.Handle;
43
+ protected parent?: Layout;
44
+ constructor(...args: Model.Args);
45
+ /** Panes in the last render. */
46
+ protected panes: number;
47
+ get row(): boolean;
48
+ /** For the element holding the panes: its ref, and the style `arrange` gives current weights. */
49
+ get rootProps(): {
50
+ ref: (element: HTMLElement | null) => void;
51
+ style: Layout.Style;
52
+ };
53
+ /** For the separator after pane `index`: role, orientation, position as a percentage, focus and resize handlers. */
54
+ get handleProps(): (index: number) => {
55
+ readonly role: "separator";
56
+ readonly 'aria-orientation': "vertical" | "horizontal";
57
+ readonly 'aria-label': "Resize";
58
+ readonly 'aria-valuemin': 0;
59
+ readonly 'aria-valuemax': 100;
60
+ readonly 'aria-valuenow': number;
61
+ readonly tabIndex: 0;
62
+ readonly onPointerDown: (event: Layout.Pointer) => void;
63
+ readonly onKeyDown: (event: Layout.Key) => void;
64
+ };
65
+ /** Style for the root laying panes out by `weights` along the axis, `gap` pixels apart. A skin supplies it. */
66
+ protected arrange(weights: number[], row: boolean, gap: number): Layout.Style;
67
+ /** Length of the root along the axis, in pixels. Defaults to the DOM's layout. */
68
+ protected measure(): number;
69
+ /**
70
+ * Report pointer moves to `move` until release or cancel, then call `end`; returns a stop for unmount mid-drag.
71
+ * Defaults to `document`.
72
+ */
73
+ protected follow(move: (event: Layout.Point) => void, end: () => void): () => void;
74
+ /** Move the handle after pane `index` by `delta` pixels. */
75
+ resize(index: number, delta: number): void;
76
+ private pixels;
77
+ private bind;
78
+ /** Start dragging the handle after pane `index`, from pointer down. */
79
+ grab(index: number, event: Layout.Pointer): void;
80
+ /** Move the handle after pane `index` by 10px per arrow key along the axis. */
81
+ nudge(index: number, event: Layout.Key): void;
82
+ render(props: {
83
+ children?: Component.Node;
84
+ }): Component.Node;
85
+ }
86
+ //#endregion
87
+ export { Layout };
88
+ //# sourceMappingURL=base.d.ts.map