@fieldia/widgets 0.12.0 → 0.13.1

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 (89) hide show
  1. package/package.json +2 -2
  2. package/src/lib/cards.js +2 -2
  3. package/src/lib/cards.js.map +1 -1
  4. package/src/lib/cards.mjs +2 -2
  5. package/src/lib/cards.mjs.map +1 -1
  6. package/src/lib/choice-tags.js +4 -2
  7. package/src/lib/choice-tags.js.map +1 -1
  8. package/src/lib/choice-tags.mjs +4 -2
  9. package/src/lib/choice-tags.mjs.map +1 -1
  10. package/src/lib/float.d.mts +14 -0
  11. package/src/lib/float.d.ts +14 -0
  12. package/src/lib/float.js +91 -0
  13. package/src/lib/float.js.map +1 -0
  14. package/src/lib/float.mjs +88 -0
  15. package/src/lib/float.mjs.map +1 -0
  16. package/src/lib/labels.d.mts +2 -0
  17. package/src/lib/labels.d.ts +2 -0
  18. package/src/lib/labels.js +1 -0
  19. package/src/lib/labels.js.map +1 -1
  20. package/src/lib/labels.mjs +1 -0
  21. package/src/lib/labels.mjs.map +1 -1
  22. package/src/lib/layout-styles.d.mts +1 -1
  23. package/src/lib/layout-styles.d.ts +1 -1
  24. package/src/lib/layout-styles.js +12 -5
  25. package/src/lib/layout-styles.js.map +1 -1
  26. package/src/lib/layout-styles.mjs +12 -5
  27. package/src/lib/layout-styles.mjs.map +1 -1
  28. package/src/lib/lines.js +123 -12
  29. package/src/lib/lines.js.map +1 -1
  30. package/src/lib/lines.mjs +123 -12
  31. package/src/lib/lines.mjs.map +1 -1
  32. package/src/lib/locales/ar.js +1 -0
  33. package/src/lib/locales/ar.js.map +1 -1
  34. package/src/lib/locales/ar.mjs +1 -0
  35. package/src/lib/locales/ar.mjs.map +1 -1
  36. package/src/lib/locales/de.js +1 -0
  37. package/src/lib/locales/de.js.map +1 -1
  38. package/src/lib/locales/de.mjs +1 -0
  39. package/src/lib/locales/de.mjs.map +1 -1
  40. package/src/lib/locales/fr.js +1 -0
  41. package/src/lib/locales/fr.js.map +1 -1
  42. package/src/lib/locales/fr.mjs +1 -0
  43. package/src/lib/locales/fr.mjs.map +1 -1
  44. package/src/lib/numbers.d.mts +5 -1
  45. package/src/lib/numbers.d.ts +5 -1
  46. package/src/lib/numbers.js +15 -2
  47. package/src/lib/numbers.js.map +1 -1
  48. package/src/lib/numbers.mjs +13 -2
  49. package/src/lib/numbers.mjs.map +1 -1
  50. package/src/lib/relations.js +11 -2
  51. package/src/lib/relations.js.map +1 -1
  52. package/src/lib/relations.mjs +11 -2
  53. package/src/lib/relations.mjs.map +1 -1
  54. package/src/lib/styles-business.d.mts +1 -1
  55. package/src/lib/styles-business.d.ts +1 -1
  56. package/src/lib/styles-business.js +1 -1
  57. package/src/lib/styles-business.mjs +1 -1
  58. package/src/lib/styles-inputs.d.mts +1 -1
  59. package/src/lib/styles-inputs.d.ts +1 -1
  60. package/src/lib/styles-inputs.js +2 -0
  61. package/src/lib/styles-inputs.js.map +1 -1
  62. package/src/lib/styles-inputs.mjs +2 -0
  63. package/src/lib/styles-inputs.mjs.map +1 -1
  64. package/src/lib/styles-kinds.d.mts +1 -1
  65. package/src/lib/styles-kinds.d.ts +1 -1
  66. package/src/lib/styles-kinds.js +1 -1
  67. package/src/lib/styles-kinds.mjs +1 -1
  68. package/src/lib/styles-sheet.d.mts +1 -1
  69. package/src/lib/styles-sheet.d.ts +1 -1
  70. package/src/lib/styles-sheet.js +28 -12
  71. package/src/lib/styles-sheet.js.map +1 -1
  72. package/src/lib/styles-sheet.mjs +28 -12
  73. package/src/lib/styles-sheet.mjs.map +1 -1
  74. package/src/lib/styles.js +83 -19
  75. package/src/lib/styles.js.map +1 -1
  76. package/src/lib/styles.mjs +83 -19
  77. package/src/lib/styles.mjs.map +1 -1
  78. package/src/lib/themes.d.mts +29 -0
  79. package/src/lib/themes.d.ts +29 -0
  80. package/src/lib/themes.js +180 -0
  81. package/src/lib/themes.js.map +1 -0
  82. package/src/lib/themes.mjs +177 -0
  83. package/src/lib/themes.mjs.map +1 -0
  84. package/src/lib/widgets.d.mts +7 -1
  85. package/src/lib/widgets.d.ts +7 -1
  86. package/src/lib/widgets.js +29 -6
  87. package/src/lib/widgets.js.map +1 -1
  88. package/src/lib/widgets.mjs +30 -7
  89. package/src/lib/widgets.mjs.map +1 -1
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.THEME_RULES_CSS = exports.THEME_TOKENS_CSS = exports.THEME_TOKENS = void 0;
4
+ const SYSTEM = 'system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", "Noto Sans Arabic", sans-serif';
5
+ exports.THEME_TOKENS = {
6
+ // Material 3's baseline: a purple primary, filled boxes on a tinted surface, pill buttons.
7
+ material: {
8
+ light: {
9
+ font: `Roboto, ${SYSTEM}`, text: '#1d1b20', muted: '#49454f', page: '#fef7ff', surface: '#ffffff', border: '#79747e', 'border-strong': '#49454f',
10
+ accent: '#6750a4', 'accent-text': '#ffffff', 'accent-soft': '#eaddff', focus: '#6750a4', 'focus-ring': 'none', error: '#b3261e', 'error-soft': '#f9dedc',
11
+ radius: '12px', 'control-radius': '4px', 'control-height': '48px', 'pad-y': '10px', 'pad-x': '16px', 'input-border': '0 0 1px 0', 'label-weight': '500', 'gap-x': '24px', 'gap-y': '20px', fill: '#ece6f0',
12
+ },
13
+ dark: {
14
+ text: '#e6e0e9', muted: '#cac4d0', page: '#141218', surface: '#1d1b20', border: '#938f99', 'border-strong': '#cac4d0',
15
+ accent: '#d0bcff', 'accent-text': '#381e72', 'accent-soft': '#4f378b', focus: '#d0bcff', error: '#f2b8b5', 'error-soft': '#601410', fill: '#36343b', edge: '#938f99',
16
+ },
17
+ },
18
+ // Fluent 2 for the web: Segoe, a darker bottom edge on boxes, a semibold primary button.
19
+ fluent: {
20
+ light: {
21
+ font: `"Segoe UI Variable Text", "Segoe UI", ${SYSTEM}`, text: '#242424', muted: '#616161', page: '#f5f5f5', surface: '#ffffff', border: '#d1d1d1', 'border-strong': '#616161',
22
+ accent: '#0f6cbd', 'accent-text': '#ffffff', 'accent-soft': '#ebf3fc', focus: '#0f6cbd', 'focus-ring': 'none', error: '#c50f1f', 'error-soft': '#fdf3f4',
23
+ radius: '8px', 'control-radius': '4px', 'control-height': '32px', 'pad-y': '5px', 'pad-x': '10px', 'input-border': '1px', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '16px',
24
+ },
25
+ dark: {
26
+ text: '#ffffff', muted: '#d6d6d6', page: '#1f1f1f', surface: '#292929', border: '#666666', 'border-strong': '#adadad',
27
+ accent: '#479ef5', 'accent-text': '#0a0a0a', 'accent-soft': '#0e4775', focus: '#479ef5', error: '#e37d80', 'error-soft': '#3b1012', edge: '#adadad',
28
+ },
29
+ },
30
+ // Apple's: grouped white cards on a pale grey, filled boxes without a frame, pill buttons, its blue.
31
+ apple: {
32
+ light: {
33
+ font: `-apple-system, BlinkMacSystemFont, "SF Pro Text", ${SYSTEM}`, text: '#1d1d1f', muted: '#6e6e73', page: '#f2f2f7', surface: '#ffffff', border: '#d1d1d6', 'border-strong': '#8e8e93',
34
+ accent: '#0066cc', 'accent-text': '#ffffff', 'accent-soft': '#e5f0fb', focus: '#0066cc', 'focus-ring': '0 0 0 4px rgba(0, 113, 227, 0.25)', error: '#d70015', 'error-soft': '#ffebec',
35
+ radius: '12px', 'control-radius': '10px', 'control-height': '40px', 'pad-y': '8px', 'pad-x': '12px', 'input-border': '1px', 'label-weight': '500', 'gap-x': '20px', 'gap-y': '16px', fill: '#f2f2f7',
36
+ },
37
+ dark: {
38
+ text: '#f5f5f7', muted: '#a1a1a6', page: '#000000', surface: '#1c1c1e', border: '#38383a', 'border-strong': '#636366',
39
+ accent: '#409cff', 'accent-text': '#000000', 'accent-soft': '#0f2b4d', focus: '#409cff', 'focus-ring': '0 0 0 4px rgba(64, 156, 255, 0.3)', error: '#ff6961', 'error-soft': '#3a1412', fill: '#2c2c2e', edge: '#636366',
40
+ },
41
+ },
42
+ // Bootstrap 5: its blue, a soft blue ring on focus, six-pixel corners.
43
+ bootstrap: {
44
+ light: {
45
+ font: SYSTEM, text: '#212529', muted: '#5c636a', page: '#f8f9fa', surface: '#ffffff', border: '#dee2e6', 'border-strong': '#adb5bd',
46
+ accent: '#0a58ca', 'accent-text': '#ffffff', 'accent-soft': '#cfe2ff', focus: '#86b7fe', 'focus-ring': '0 0 0 0.25rem rgba(13, 110, 253, 0.25)', error: '#b02a37', 'error-soft': '#f8d7da',
47
+ radius: '6px', 'control-radius': '6px', 'control-height': '38px', 'pad-y': '6px', 'pad-x': '12px', 'input-border': '1px', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '16px',
48
+ },
49
+ dark: {
50
+ text: '#dee2e6', muted: '#adb5bd', page: '#212529', surface: '#2b3035', border: '#495057', 'border-strong': '#6c757d',
51
+ accent: '#6ea8fe', 'accent-text': '#000000', 'accent-soft': '#031633', focus: '#6ea8fe', 'focus-ring': '0 0 0 0.25rem rgba(110, 168, 254, 0.25)', error: '#ea868f', 'error-soft': '#2c0b0e', edge: '#6c757d',
52
+ },
53
+ },
54
+ // shadcn/ui on zinc: near-black primary, quiet borders, a grey ring, segmented tabs.
55
+ shadcn: {
56
+ light: {
57
+ font: `Geist, Inter, ${SYSTEM}`, text: '#09090b', muted: '#64646c', page: '#fafafa', surface: '#ffffff', border: '#e4e4e7', 'border-strong': '#a1a1aa',
58
+ accent: '#18181b', 'accent-text': '#fafafa', 'accent-soft': '#f4f4f5', focus: '#a1a1aa', 'focus-ring': '0 0 0 3px rgba(161, 161, 170, 0.5)', error: '#dc2626', 'error-soft': '#fef2f2',
59
+ radius: '10px', 'control-radius': '8px', 'control-height': '36px', 'pad-y': '6px', 'pad-x': '12px', 'input-border': '1px', 'label-weight': '500', 'gap-x': '24px', 'gap-y': '16px',
60
+ },
61
+ dark: {
62
+ text: '#fafafa', muted: '#a1a1aa', page: '#09090b', surface: '#18181b', border: '#3f3f46', 'border-strong': '#71717a',
63
+ accent: '#e4e4e7', 'accent-text': '#18181b', 'accent-soft': '#27272a', focus: '#71717a', 'focus-ring': '0 0 0 3px rgba(113, 113, 122, 0.5)', error: '#f87171', 'error-soft': '#450a0a', edge: '#71717a',
64
+ },
65
+ },
66
+ // Ant Design 5: the outlined skin's own tokens, and its dark algorithm.
67
+ ant: {
68
+ light: {
69
+ font: SYSTEM, text: 'rgba(0, 0, 0, 0.88)', muted: 'rgba(0, 0, 0, 0.55)', page: '#f5f5f5', surface: '#ffffff', border: '#d9d9d9', 'border-strong': '#bfbfbf',
70
+ accent: '#1365d9', 'accent-text': '#ffffff', 'accent-soft': '#e6f4ff', focus: '#1365d9', 'focus-ring': '0 0 0 2px rgba(5, 145, 255, 0.12)', error: '#c63c3d', 'error-soft': '#fff2f0',
71
+ radius: '8px', 'control-radius': '6px', 'pad-y': '4px', 'pad-x': '11px', 'input-border': '1px', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '18px',
72
+ },
73
+ dark: {
74
+ text: 'rgba(255, 255, 255, 0.85)', muted: 'rgba(255, 255, 255, 0.6)', page: '#000000', surface: '#141414', border: '#424242', 'border-strong': '#595959',
75
+ accent: '#3c89e8', 'accent-text': '#000000', 'accent-soft': '#111a2c', focus: '#3c89e8', 'focus-ring': '0 0 0 2px rgba(60, 137, 232, 0.2)', error: '#e86e6b', 'error-soft': '#2c1618', edge: '#595959',
76
+ },
77
+ },
78
+ // Odoo 17: labels beside underlined boxes, its plum for buttons and the picked tab.
79
+ odoo: {
80
+ light: {
81
+ font: SYSTEM, text: '#1f2937', muted: '#4b5563', page: '#f9fafb', surface: '#ffffff', border: '#d1d5db', 'border-strong': '#9ca3af',
82
+ accent: '#714b67', 'accent-text': '#ffffff', 'accent-soft': '#f3edf2', focus: '#714b67', 'focus-ring': 'none', error: '#c4161c', 'error-soft': '#fdecec',
83
+ radius: '4px', 'control-radius': '0px', 'pad-y': '3px', 'pad-x': '4px', 'input-border': '0 0 1px 0', 'label-weight': '600', 'gap-x': '32px', 'gap-y': '14px',
84
+ },
85
+ dark: {
86
+ text: '#e5e7eb', muted: '#9ca3af', page: '#111827', surface: '#1f2937', border: '#4b5563', 'border-strong': '#6b7280',
87
+ accent: '#c79fbc', 'accent-text': '#1f1020', 'accent-soft': '#3b2836', focus: '#c79fbc', error: '#f6878b', 'error-soft': '#3a1214', edge: '#6b7280',
88
+ },
89
+ },
90
+ // Google Forms: each question a white card on a tinted page, a purple band over the title, underlined answers.
91
+ 'google-forms': {
92
+ light: {
93
+ font: `Roboto, Arial, ${SYSTEM}`, text: '#202124', muted: '#5f6368', page: '#f0ebf8', surface: '#ffffff', border: '#dadce0', 'border-strong': '#80868b',
94
+ accent: '#673ab7', 'accent-text': '#ffffff', 'accent-soft': '#ede7f6', focus: '#673ab7', 'focus-ring': 'none', error: '#d93025', 'error-soft': '#fce8e6',
95
+ radius: '8px', 'control-radius': '0px', 'control-height': '36px', 'pad-y': '6px', 'pad-x': '0px', 'input-border': '0 0 1px 0', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '12px',
96
+ },
97
+ dark: {
98
+ text: '#e8e3ee', muted: '#b8b0c4', page: '#1c1822', surface: '#2a2431', border: '#4a4255', 'border-strong': '#7b7088',
99
+ accent: '#c4abf2', 'accent-text': '#1d1528', 'accent-soft': '#3b2f52', focus: '#c4abf2', error: '#f28b82', 'error-soft': '#3c1714', edge: '#7b7088',
100
+ },
101
+ },
102
+ };
103
+ const block = (tokens) => Object.entries(tokens)
104
+ .map(([name, value]) => `--fd-${name}: ${value};`)
105
+ .join(' ');
106
+ const forms = (theme) => `:is(.fd-form, .fd-form-dialog, .fd-theme)[data-fd-theme="${theme}"]`;
107
+ /** A group drawn as a card on the page's ground, as the outlined skin draws one: on the page, or set as a card. */
108
+ const CARDS = ':is(.fd-sections > .fd-section:not([data-style]), .fd-section[data-style="card"][data-on-page])';
109
+ /**
110
+ * The themes' tokens: after the skins' (they win over them), before the page's
111
+ * look (whose accent, room, corners and scheme win over them). A theme's dark
112
+ * tokens are more specific than the plain dark scheme's, so they win over it.
113
+ * All in Fieldia's tokens' layer, under any rule of a host's own.
114
+ */
115
+ exports.THEME_TOKENS_CSS = Object.keys(exports.THEME_TOKENS)
116
+ .map((theme) => {
117
+ const { light, dark } = exports.THEME_TOKENS[theme];
118
+ const darkOn = `${forms(theme)}[data-scheme="dark"]`;
119
+ return `${forms(theme)} { ${block(light)} }
120
+ ${darkOn} { ${block(dark)} }
121
+ @media (prefers-color-scheme: dark) { ${forms(theme)}[data-scheme="auto"] { ${block(dark)} } }`;
122
+ })
123
+ .join('\n')
124
+ // In Fieldia's tokens' layer (styles.ts), after the skins': a host's own rule sets them over a theme's too.
125
+ .replace(/^/, '@layer fieldia-tokens {\n')
126
+ .concat('\n}');
127
+ /** What tokens cannot say: each theme's own shapes. After every other rule, so they win at the same weight. */
128
+ exports.THEME_RULES_CSS = `
129
+ /* A themed form paints its own ground, as one with a scheme does: Google Forms' lilac, Apple's grey. In a dialog, the dialog is its ground. */
130
+ .fd-form[data-fd-theme] { background: var(--fd-page); color: var(--fd-text); border-radius: var(--fd-radius); }
131
+ .fd-form[data-fd-theme] > .fd-content:not(:has(> .fd-sheet-page)) { padding: 20px; }
132
+ .fd-form-dialog-body > .fd-form[data-fd-theme] { background: none; border-radius: 0; }
133
+ .fd-form-dialog-body > .fd-form[data-fd-theme] > .fd-content:not(:has(> .fd-sheet-page)) { padding: 0; }
134
+ /* Material: boxes filled and underlined, the line thickening on focus; pill buttons; borderless tinted cards. */
135
+ ${forms('material')} .fd-input:not([readonly]) { background: var(--fd-fill); border-start-start-radius: var(--fd-control-radius); border-start-end-radius: var(--fd-control-radius); border-end-start-radius: 0; border-end-end-radius: 0; }
136
+ ${forms('material')} .fd-input:focus { box-shadow: inset 0 -1px 0 0 var(--fd-focus); }
137
+ ${forms('material')} .fd-button { border-radius: 20px; min-height: 40px; padding-inline: 24px; font-weight: 500; letter-spacing: 0.01em; border-color: var(--fd-border); }
138
+ ${forms('material')} .fd-tab[aria-selected="true"] { border-block-end-width: 3px; }
139
+ ${forms('material')} ${CARDS} { border-color: transparent; background: color-mix(in srgb, var(--fd-accent) 4%, var(--fd-surface)); }
140
+
141
+ /* Fluent: a darker bottom edge under every box, an accent bar on focus; semibold buttons; the picked tab in words, not the accent. */
142
+ ${forms('fluent')} .fd-input:not([readonly]) { border-block-end-color: var(--fd-border-strong); }
143
+ ${forms('fluent')} .fd-input:focus { box-shadow: inset 0 -2px 0 0 var(--fd-focus); border-block-end-color: var(--fd-focus); }
144
+ ${forms('fluent')} .fd-button { font-weight: 600; }
145
+ ${forms('fluent')} .fd-tab[aria-selected="true"] { color: var(--fd-text); border-block-end-width: 3px; }
146
+
147
+ /* Apple: boxes filled, no frame until focused; pill buttons; grouped cards with no edge. */
148
+ ${forms('apple')} .fd-input:not([readonly]) { background: var(--fd-fill); border-color: transparent; }
149
+ ${forms('apple')} .fd-input:not([readonly]):focus { background: var(--fd-surface); border-color: var(--fd-focus); }
150
+ ${forms('apple')} .fd-button { border-radius: 980px; padding-inline: 18px; font-weight: 500; }
151
+ ${forms('apple')} ${CARDS} { border-color: transparent; }
152
+
153
+ /* Bootstrap: its buttons' weight and padding. */
154
+ ${forms('bootstrap')} .fd-button { padding-inline: 12px; }
155
+
156
+ /* shadcn: a hairline shadow under boxes and buttons; the picked tab a raised segment on a grey strip. */
157
+ ${forms('shadcn')} :is(.fd-input:not([readonly]), .fd-button:not(.fd-button-link)) { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); }
158
+ ${forms('shadcn')} .fd-input:focus { box-shadow: var(--fd-focus-ring); }
159
+ ${forms('shadcn')} .fd-button { font-weight: 500; }
160
+ ${forms('shadcn')} .fd-button:hover { color: var(--fd-text); background: var(--fd-accent-soft); border-color: var(--fd-border); }
161
+ ${forms('shadcn')} .fd-button-primary:hover { color: var(--fd-accent-text); background: var(--fd-accent); filter: brightness(1.25); }
162
+ ${forms('shadcn')} .fd-tablist { gap: 2px; padding: 3px; border: 0; border-radius: var(--fd-radius); background: var(--fd-accent-soft); width: max-content; max-width: 100%; }
163
+ ${forms('shadcn')} .fd-tab { border: 0; margin: 0; padding: 5px 12px; border-radius: calc(var(--fd-radius) - 3px); color: var(--fd-muted); }
164
+ ${forms('shadcn')} .fd-tab[aria-selected="true"] { color: var(--fd-text); background: var(--fd-surface); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); font-weight: 500; }
165
+
166
+ /* Odoo: square buttons with small corners. */
167
+ ${forms('odoo')} .fd-button { border-radius: 4px; }
168
+
169
+ /* Google Forms: the title a card with a band of the accent along its top; each question its own card; answers underlined. */
170
+ ${forms('google-forms')} .fd-page-head { background: var(--fd-surface); border: 1px solid var(--fd-border); border-block-start: 10px solid var(--fd-accent); border-radius: var(--fd-radius); padding: 22px 24px; }
171
+ ${forms('google-forms')} .fd-page-title { font-size: 32px; font-weight: 400; line-height: 1.2; }
172
+ ${forms('google-forms')} ${CARDS} { background: none; border: 0; padding: 0; }
173
+ ${forms('google-forms')} ${CARDS} > .fd-grid > .fd-field:not(.fd-oneline) { background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); padding: 22px 24px; }
174
+ ${forms('google-forms')} ${CARDS} > .fd-grid > .fd-field:focus-within { border-inline-start: 6px solid var(--fd-accent); padding-inline-start: 19px; }
175
+ ${forms('google-forms')} .fd-label { font-size: 16px; }
176
+ ${forms('google-forms')} .fd-input:not([readonly]) { background: transparent; }
177
+ ${forms('google-forms')} .fd-input:focus { box-shadow: inset 0 -1px 0 0 var(--fd-focus); }
178
+ ${forms('google-forms')} .fd-button { border-radius: 4px; font-weight: 500; }
179
+ `;
180
+ //# sourceMappingURL=themes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/themes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ const SYSTEM = 'system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", "Noto Sans Arabic", sans-serif';
2
+ export const THEME_TOKENS = {
3
+ // Material 3's baseline: a purple primary, filled boxes on a tinted surface, pill buttons.
4
+ material: {
5
+ light: {
6
+ font: `Roboto, ${SYSTEM}`, text: '#1d1b20', muted: '#49454f', page: '#fef7ff', surface: '#ffffff', border: '#79747e', 'border-strong': '#49454f',
7
+ accent: '#6750a4', 'accent-text': '#ffffff', 'accent-soft': '#eaddff', focus: '#6750a4', 'focus-ring': 'none', error: '#b3261e', 'error-soft': '#f9dedc',
8
+ radius: '12px', 'control-radius': '4px', 'control-height': '48px', 'pad-y': '10px', 'pad-x': '16px', 'input-border': '0 0 1px 0', 'label-weight': '500', 'gap-x': '24px', 'gap-y': '20px', fill: '#ece6f0',
9
+ },
10
+ dark: {
11
+ text: '#e6e0e9', muted: '#cac4d0', page: '#141218', surface: '#1d1b20', border: '#938f99', 'border-strong': '#cac4d0',
12
+ accent: '#d0bcff', 'accent-text': '#381e72', 'accent-soft': '#4f378b', focus: '#d0bcff', error: '#f2b8b5', 'error-soft': '#601410', fill: '#36343b', edge: '#938f99',
13
+ },
14
+ },
15
+ // Fluent 2 for the web: Segoe, a darker bottom edge on boxes, a semibold primary button.
16
+ fluent: {
17
+ light: {
18
+ font: `"Segoe UI Variable Text", "Segoe UI", ${SYSTEM}`, text: '#242424', muted: '#616161', page: '#f5f5f5', surface: '#ffffff', border: '#d1d1d1', 'border-strong': '#616161',
19
+ accent: '#0f6cbd', 'accent-text': '#ffffff', 'accent-soft': '#ebf3fc', focus: '#0f6cbd', 'focus-ring': 'none', error: '#c50f1f', 'error-soft': '#fdf3f4',
20
+ radius: '8px', 'control-radius': '4px', 'control-height': '32px', 'pad-y': '5px', 'pad-x': '10px', 'input-border': '1px', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '16px',
21
+ },
22
+ dark: {
23
+ text: '#ffffff', muted: '#d6d6d6', page: '#1f1f1f', surface: '#292929', border: '#666666', 'border-strong': '#adadad',
24
+ accent: '#479ef5', 'accent-text': '#0a0a0a', 'accent-soft': '#0e4775', focus: '#479ef5', error: '#e37d80', 'error-soft': '#3b1012', edge: '#adadad',
25
+ },
26
+ },
27
+ // Apple's: grouped white cards on a pale grey, filled boxes without a frame, pill buttons, its blue.
28
+ apple: {
29
+ light: {
30
+ font: `-apple-system, BlinkMacSystemFont, "SF Pro Text", ${SYSTEM}`, text: '#1d1d1f', muted: '#6e6e73', page: '#f2f2f7', surface: '#ffffff', border: '#d1d1d6', 'border-strong': '#8e8e93',
31
+ accent: '#0066cc', 'accent-text': '#ffffff', 'accent-soft': '#e5f0fb', focus: '#0066cc', 'focus-ring': '0 0 0 4px rgba(0, 113, 227, 0.25)', error: '#d70015', 'error-soft': '#ffebec',
32
+ radius: '12px', 'control-radius': '10px', 'control-height': '40px', 'pad-y': '8px', 'pad-x': '12px', 'input-border': '1px', 'label-weight': '500', 'gap-x': '20px', 'gap-y': '16px', fill: '#f2f2f7',
33
+ },
34
+ dark: {
35
+ text: '#f5f5f7', muted: '#a1a1a6', page: '#000000', surface: '#1c1c1e', border: '#38383a', 'border-strong': '#636366',
36
+ accent: '#409cff', 'accent-text': '#000000', 'accent-soft': '#0f2b4d', focus: '#409cff', 'focus-ring': '0 0 0 4px rgba(64, 156, 255, 0.3)', error: '#ff6961', 'error-soft': '#3a1412', fill: '#2c2c2e', edge: '#636366',
37
+ },
38
+ },
39
+ // Bootstrap 5: its blue, a soft blue ring on focus, six-pixel corners.
40
+ bootstrap: {
41
+ light: {
42
+ font: SYSTEM, text: '#212529', muted: '#5c636a', page: '#f8f9fa', surface: '#ffffff', border: '#dee2e6', 'border-strong': '#adb5bd',
43
+ accent: '#0a58ca', 'accent-text': '#ffffff', 'accent-soft': '#cfe2ff', focus: '#86b7fe', 'focus-ring': '0 0 0 0.25rem rgba(13, 110, 253, 0.25)', error: '#b02a37', 'error-soft': '#f8d7da',
44
+ radius: '6px', 'control-radius': '6px', 'control-height': '38px', 'pad-y': '6px', 'pad-x': '12px', 'input-border': '1px', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '16px',
45
+ },
46
+ dark: {
47
+ text: '#dee2e6', muted: '#adb5bd', page: '#212529', surface: '#2b3035', border: '#495057', 'border-strong': '#6c757d',
48
+ accent: '#6ea8fe', 'accent-text': '#000000', 'accent-soft': '#031633', focus: '#6ea8fe', 'focus-ring': '0 0 0 0.25rem rgba(110, 168, 254, 0.25)', error: '#ea868f', 'error-soft': '#2c0b0e', edge: '#6c757d',
49
+ },
50
+ },
51
+ // shadcn/ui on zinc: near-black primary, quiet borders, a grey ring, segmented tabs.
52
+ shadcn: {
53
+ light: {
54
+ font: `Geist, Inter, ${SYSTEM}`, text: '#09090b', muted: '#64646c', page: '#fafafa', surface: '#ffffff', border: '#e4e4e7', 'border-strong': '#a1a1aa',
55
+ accent: '#18181b', 'accent-text': '#fafafa', 'accent-soft': '#f4f4f5', focus: '#a1a1aa', 'focus-ring': '0 0 0 3px rgba(161, 161, 170, 0.5)', error: '#dc2626', 'error-soft': '#fef2f2',
56
+ radius: '10px', 'control-radius': '8px', 'control-height': '36px', 'pad-y': '6px', 'pad-x': '12px', 'input-border': '1px', 'label-weight': '500', 'gap-x': '24px', 'gap-y': '16px',
57
+ },
58
+ dark: {
59
+ text: '#fafafa', muted: '#a1a1aa', page: '#09090b', surface: '#18181b', border: '#3f3f46', 'border-strong': '#71717a',
60
+ accent: '#e4e4e7', 'accent-text': '#18181b', 'accent-soft': '#27272a', focus: '#71717a', 'focus-ring': '0 0 0 3px rgba(113, 113, 122, 0.5)', error: '#f87171', 'error-soft': '#450a0a', edge: '#71717a',
61
+ },
62
+ },
63
+ // Ant Design 5: the outlined skin's own tokens, and its dark algorithm.
64
+ ant: {
65
+ light: {
66
+ font: SYSTEM, text: 'rgba(0, 0, 0, 0.88)', muted: 'rgba(0, 0, 0, 0.55)', page: '#f5f5f5', surface: '#ffffff', border: '#d9d9d9', 'border-strong': '#bfbfbf',
67
+ accent: '#1365d9', 'accent-text': '#ffffff', 'accent-soft': '#e6f4ff', focus: '#1365d9', 'focus-ring': '0 0 0 2px rgba(5, 145, 255, 0.12)', error: '#c63c3d', 'error-soft': '#fff2f0',
68
+ radius: '8px', 'control-radius': '6px', 'pad-y': '4px', 'pad-x': '11px', 'input-border': '1px', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '18px',
69
+ },
70
+ dark: {
71
+ text: 'rgba(255, 255, 255, 0.85)', muted: 'rgba(255, 255, 255, 0.6)', page: '#000000', surface: '#141414', border: '#424242', 'border-strong': '#595959',
72
+ accent: '#3c89e8', 'accent-text': '#000000', 'accent-soft': '#111a2c', focus: '#3c89e8', 'focus-ring': '0 0 0 2px rgba(60, 137, 232, 0.2)', error: '#e86e6b', 'error-soft': '#2c1618', edge: '#595959',
73
+ },
74
+ },
75
+ // Odoo 17: labels beside underlined boxes, its plum for buttons and the picked tab.
76
+ odoo: {
77
+ light: {
78
+ font: SYSTEM, text: '#1f2937', muted: '#4b5563', page: '#f9fafb', surface: '#ffffff', border: '#d1d5db', 'border-strong': '#9ca3af',
79
+ accent: '#714b67', 'accent-text': '#ffffff', 'accent-soft': '#f3edf2', focus: '#714b67', 'focus-ring': 'none', error: '#c4161c', 'error-soft': '#fdecec',
80
+ radius: '4px', 'control-radius': '0px', 'pad-y': '3px', 'pad-x': '4px', 'input-border': '0 0 1px 0', 'label-weight': '600', 'gap-x': '32px', 'gap-y': '14px',
81
+ },
82
+ dark: {
83
+ text: '#e5e7eb', muted: '#9ca3af', page: '#111827', surface: '#1f2937', border: '#4b5563', 'border-strong': '#6b7280',
84
+ accent: '#c79fbc', 'accent-text': '#1f1020', 'accent-soft': '#3b2836', focus: '#c79fbc', error: '#f6878b', 'error-soft': '#3a1214', edge: '#6b7280',
85
+ },
86
+ },
87
+ // Google Forms: each question a white card on a tinted page, a purple band over the title, underlined answers.
88
+ 'google-forms': {
89
+ light: {
90
+ font: `Roboto, Arial, ${SYSTEM}`, text: '#202124', muted: '#5f6368', page: '#f0ebf8', surface: '#ffffff', border: '#dadce0', 'border-strong': '#80868b',
91
+ accent: '#673ab7', 'accent-text': '#ffffff', 'accent-soft': '#ede7f6', focus: '#673ab7', 'focus-ring': 'none', error: '#d93025', 'error-soft': '#fce8e6',
92
+ radius: '8px', 'control-radius': '0px', 'control-height': '36px', 'pad-y': '6px', 'pad-x': '0px', 'input-border': '0 0 1px 0', 'label-weight': '400', 'gap-x': '24px', 'gap-y': '12px',
93
+ },
94
+ dark: {
95
+ text: '#e8e3ee', muted: '#b8b0c4', page: '#1c1822', surface: '#2a2431', border: '#4a4255', 'border-strong': '#7b7088',
96
+ accent: '#c4abf2', 'accent-text': '#1d1528', 'accent-soft': '#3b2f52', focus: '#c4abf2', error: '#f28b82', 'error-soft': '#3c1714', edge: '#7b7088',
97
+ },
98
+ },
99
+ };
100
+ const block = (tokens) => Object.entries(tokens)
101
+ .map(([name, value]) => `--fd-${name}: ${value};`)
102
+ .join(' ');
103
+ const forms = (theme) => `:is(.fd-form, .fd-form-dialog, .fd-theme)[data-fd-theme="${theme}"]`;
104
+ /** A group drawn as a card on the page's ground, as the outlined skin draws one: on the page, or set as a card. */
105
+ const CARDS = ':is(.fd-sections > .fd-section:not([data-style]), .fd-section[data-style="card"][data-on-page])';
106
+ /**
107
+ * The themes' tokens: after the skins' (they win over them), before the page's
108
+ * look (whose accent, room, corners and scheme win over them). A theme's dark
109
+ * tokens are more specific than the plain dark scheme's, so they win over it.
110
+ * All in Fieldia's tokens' layer, under any rule of a host's own.
111
+ */
112
+ export const THEME_TOKENS_CSS = Object.keys(THEME_TOKENS)
113
+ .map((theme) => {
114
+ const { light, dark } = THEME_TOKENS[theme];
115
+ const darkOn = `${forms(theme)}[data-scheme="dark"]`;
116
+ return `${forms(theme)} { ${block(light)} }
117
+ ${darkOn} { ${block(dark)} }
118
+ @media (prefers-color-scheme: dark) { ${forms(theme)}[data-scheme="auto"] { ${block(dark)} } }`;
119
+ })
120
+ .join('\n')
121
+ // In Fieldia's tokens' layer (styles.ts), after the skins': a host's own rule sets them over a theme's too.
122
+ .replace(/^/, '@layer fieldia-tokens {\n')
123
+ .concat('\n}');
124
+ /** What tokens cannot say: each theme's own shapes. After every other rule, so they win at the same weight. */
125
+ export const THEME_RULES_CSS = /* css */ `
126
+ /* A themed form paints its own ground, as one with a scheme does: Google Forms' lilac, Apple's grey. In a dialog, the dialog is its ground. */
127
+ .fd-form[data-fd-theme] { background: var(--fd-page); color: var(--fd-text); border-radius: var(--fd-radius); }
128
+ .fd-form[data-fd-theme] > .fd-content:not(:has(> .fd-sheet-page)) { padding: 20px; }
129
+ .fd-form-dialog-body > .fd-form[data-fd-theme] { background: none; border-radius: 0; }
130
+ .fd-form-dialog-body > .fd-form[data-fd-theme] > .fd-content:not(:has(> .fd-sheet-page)) { padding: 0; }
131
+ /* Material: boxes filled and underlined, the line thickening on focus; pill buttons; borderless tinted cards. */
132
+ ${forms('material')} .fd-input:not([readonly]) { background: var(--fd-fill); border-start-start-radius: var(--fd-control-radius); border-start-end-radius: var(--fd-control-radius); border-end-start-radius: 0; border-end-end-radius: 0; }
133
+ ${forms('material')} .fd-input:focus { box-shadow: inset 0 -1px 0 0 var(--fd-focus); }
134
+ ${forms('material')} .fd-button { border-radius: 20px; min-height: 40px; padding-inline: 24px; font-weight: 500; letter-spacing: 0.01em; border-color: var(--fd-border); }
135
+ ${forms('material')} .fd-tab[aria-selected="true"] { border-block-end-width: 3px; }
136
+ ${forms('material')} ${CARDS} { border-color: transparent; background: color-mix(in srgb, var(--fd-accent) 4%, var(--fd-surface)); }
137
+
138
+ /* Fluent: a darker bottom edge under every box, an accent bar on focus; semibold buttons; the picked tab in words, not the accent. */
139
+ ${forms('fluent')} .fd-input:not([readonly]) { border-block-end-color: var(--fd-border-strong); }
140
+ ${forms('fluent')} .fd-input:focus { box-shadow: inset 0 -2px 0 0 var(--fd-focus); border-block-end-color: var(--fd-focus); }
141
+ ${forms('fluent')} .fd-button { font-weight: 600; }
142
+ ${forms('fluent')} .fd-tab[aria-selected="true"] { color: var(--fd-text); border-block-end-width: 3px; }
143
+
144
+ /* Apple: boxes filled, no frame until focused; pill buttons; grouped cards with no edge. */
145
+ ${forms('apple')} .fd-input:not([readonly]) { background: var(--fd-fill); border-color: transparent; }
146
+ ${forms('apple')} .fd-input:not([readonly]):focus { background: var(--fd-surface); border-color: var(--fd-focus); }
147
+ ${forms('apple')} .fd-button { border-radius: 980px; padding-inline: 18px; font-weight: 500; }
148
+ ${forms('apple')} ${CARDS} { border-color: transparent; }
149
+
150
+ /* Bootstrap: its buttons' weight and padding. */
151
+ ${forms('bootstrap')} .fd-button { padding-inline: 12px; }
152
+
153
+ /* shadcn: a hairline shadow under boxes and buttons; the picked tab a raised segment on a grey strip. */
154
+ ${forms('shadcn')} :is(.fd-input:not([readonly]), .fd-button:not(.fd-button-link)) { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); }
155
+ ${forms('shadcn')} .fd-input:focus { box-shadow: var(--fd-focus-ring); }
156
+ ${forms('shadcn')} .fd-button { font-weight: 500; }
157
+ ${forms('shadcn')} .fd-button:hover { color: var(--fd-text); background: var(--fd-accent-soft); border-color: var(--fd-border); }
158
+ ${forms('shadcn')} .fd-button-primary:hover { color: var(--fd-accent-text); background: var(--fd-accent); filter: brightness(1.25); }
159
+ ${forms('shadcn')} .fd-tablist { gap: 2px; padding: 3px; border: 0; border-radius: var(--fd-radius); background: var(--fd-accent-soft); width: max-content; max-width: 100%; }
160
+ ${forms('shadcn')} .fd-tab { border: 0; margin: 0; padding: 5px 12px; border-radius: calc(var(--fd-radius) - 3px); color: var(--fd-muted); }
161
+ ${forms('shadcn')} .fd-tab[aria-selected="true"] { color: var(--fd-text); background: var(--fd-surface); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); font-weight: 500; }
162
+
163
+ /* Odoo: square buttons with small corners. */
164
+ ${forms('odoo')} .fd-button { border-radius: 4px; }
165
+
166
+ /* Google Forms: the title a card with a band of the accent along its top; each question its own card; answers underlined. */
167
+ ${forms('google-forms')} .fd-page-head { background: var(--fd-surface); border: 1px solid var(--fd-border); border-block-start: 10px solid var(--fd-accent); border-radius: var(--fd-radius); padding: 22px 24px; }
168
+ ${forms('google-forms')} .fd-page-title { font-size: 32px; font-weight: 400; line-height: 1.2; }
169
+ ${forms('google-forms')} ${CARDS} { background: none; border: 0; padding: 0; }
170
+ ${forms('google-forms')} ${CARDS} > .fd-grid > .fd-field:not(.fd-oneline) { background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); padding: 22px 24px; }
171
+ ${forms('google-forms')} ${CARDS} > .fd-grid > .fd-field:focus-within { border-inline-start: 6px solid var(--fd-accent); padding-inline-start: 19px; }
172
+ ${forms('google-forms')} .fd-label { font-size: 16px; }
173
+ ${forms('google-forms')} .fd-input:not([readonly]) { background: transparent; }
174
+ ${forms('google-forms')} .fd-input:focus { box-shadow: inset 0 -1px 0 0 var(--fd-focus); }
175
+ ${forms('google-forms')} .fd-button { border-radius: 4px; font-weight: 500; }
176
+ `;
177
+ //# sourceMappingURL=themes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/themes.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,GAAG,2FAA2F,CAAC;AAE3G,MAAM,CAAC,MAAM,YAAY,GAA6D;IACpF,2FAA2F;IAC3F,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,IAAI,EAAE,WAAW,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YAChJ,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACxJ,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS;SAC3M;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACrK;KACF;IACD,yFAAyF;IACzF,MAAM,EAAE;QACN,KAAK,EAAE;YACL,IAAI,EAAE,yCAAyC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YAC9K,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACxJ,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;SAClL;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACpJ;KACF;IACD,qGAAqG;IACrG,KAAK,EAAE;QACL,KAAK,EAAE;YACL,IAAI,EAAE,qDAAqD,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YAC1L,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,mCAAmC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACrL,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS;SACrM;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,mCAAmC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACxN;KACF;IACD,uEAAuE;IACvE,SAAS,EAAE;QACT,KAAK,EAAE;YACL,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACnI,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,wCAAwC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YAC1L,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;SAClL;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,yCAAyC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SAC7M;KACF;IACD,qFAAqF;IACrF,MAAM,EAAE;QACN,KAAK,EAAE;YACL,IAAI,EAAE,iBAAiB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACtJ,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,oCAAoC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACtL,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;SACnL;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,oCAAoC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACxM;KACF;IACD,wEAAwE;IACxE,GAAG,EAAE;QACH,KAAK,EAAE;YACL,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YAC3J,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,mCAAmC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACrL,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;SACxJ;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACxJ,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,mCAAmC,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACvM;KACF;IACD,oFAAoF;IACpF,IAAI,EAAE;QACJ,KAAK,EAAE;YACL,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACnI,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACxJ,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;SAC7J;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACpJ;KACF;IACD,+GAA+G;IAC/G,cAAc,EAAE;QACd,KAAK,EAAE;YACL,IAAI,EAAE,kBAAkB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACvJ,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS;YACxJ,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;SACvL;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS;YACrH,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;SACpJ;KACF;CACF,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,MAAmB,EAAE,EAAE,CACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;KACnB,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,QAAQ,IAAI,KAAK,KAAK,GAAG,CAAC;KACjD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,4DAA4D,KAAK,IAAI,CAAC;AACtG,mHAAmH;AACnH,MAAM,KAAK,GAAG,iGAAiG,CAAC;AAEhH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAa;KACnE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC;IACrD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC;EAC1C,MAAM,MAAM,KAAK,CAAC,IAAI,CAAC;wCACe,KAAK,CAAC,KAAK,CAAC,0BAA0B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AAC9F,CAAC,CAAC;KACD,IAAI,CAAC,IAAI,CAAC;IACX,4GAA4G;KAC3G,OAAO,CAAC,GAAG,EAAE,2BAA2B,CAAC;KACzC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEjB,+GAA+G;AAC/G,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;;;;;;;EAOvC,KAAK,CAAC,UAAU,CAAC;EACjB,KAAK,CAAC,UAAU,CAAC;EACjB,KAAK,CAAC,UAAU,CAAC;EACjB,KAAK,CAAC,UAAU,CAAC;EACjB,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK;;;EAG1B,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;;;EAGf,KAAK,CAAC,OAAO,CAAC;EACd,KAAK,CAAC,OAAO,CAAC;EACd,KAAK,CAAC,OAAO,CAAC;EACd,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK;;;EAGvB,KAAK,CAAC,WAAW,CAAC;;;EAGlB,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;EACf,KAAK,CAAC,QAAQ,CAAC;;;EAGf,KAAK,CAAC,MAAM,CAAC;;;EAGb,KAAK,CAAC,cAAc,CAAC;EACrB,KAAK,CAAC,cAAc,CAAC;EACrB,KAAK,CAAC,cAAc,CAAC,IAAI,KAAK;EAC9B,KAAK,CAAC,cAAc,CAAC,IAAI,KAAK;EAC9B,KAAK,CAAC,cAAc,CAAC,IAAI,KAAK;EAC9B,KAAK,CAAC,cAAc,CAAC;EACrB,KAAK,CAAC,cAAc,CAAC;EACrB,KAAK,CAAC,cAAc,CAAC;EACrB,KAAK,CAAC,cAAc,CAAC;CACtB,CAAC"}
@@ -23,6 +23,12 @@ export interface WidgetContext {
23
23
  locale?: Locale;
24
24
  /** Dialogs the page can open: a related record, a searchable list, values to edit. Left out, widgets offer none. */
25
25
  dialogs?: WidgetDialogs;
26
+ /**
27
+ * The app's widgets, by `type` or `type.widget`, as given to the viewer. A
28
+ * widget that draws fields of its own (a table's cells, a property's value)
29
+ * draws them from these too, so a column can name one as a field can.
30
+ */
31
+ widgets?: Record<string, WidgetFactory>;
26
32
  }
27
33
  /** What a widget may ask of the page around it in a dialog. The viewer provides these. */
28
34
  export interface WidgetDialogs {
@@ -91,6 +97,6 @@ export type WidgetFactory = (context: WidgetContext) => Widget;
91
97
  * `type.widget` (such as `selection.radio`), then for the type alone. A type
92
98
  * with no editor yet shows its value read-only.
93
99
  */
94
- export declare function createWidget(context: WidgetContext, registry?: Record<string, WidgetFactory>): Widget;
100
+ export declare function createWidget(given: WidgetContext, registry?: Record<string, WidgetFactory>): Widget;
95
101
  export declare function summary(value: Value | undefined, field: Field): string;
96
102
  export declare const builtInWidgets: Record<string, WidgetFactory>;
@@ -23,6 +23,12 @@ export interface WidgetContext {
23
23
  locale?: Locale;
24
24
  /** Dialogs the page can open: a related record, a searchable list, values to edit. Left out, widgets offer none. */
25
25
  dialogs?: WidgetDialogs;
26
+ /**
27
+ * The app's widgets, by `type` or `type.widget`, as given to the viewer. A
28
+ * widget that draws fields of its own (a table's cells, a property's value)
29
+ * draws them from these too, so a column can name one as a field can.
30
+ */
31
+ widgets?: Record<string, WidgetFactory>;
26
32
  }
27
33
  /** What a widget may ask of the page around it in a dialog. The viewer provides these. */
28
34
  export interface WidgetDialogs {
@@ -91,6 +97,6 @@ export type WidgetFactory = (context: WidgetContext) => Widget;
91
97
  * `type.widget` (such as `selection.radio`), then for the type alone. A type
92
98
  * with no editor yet shows its value read-only.
93
99
  */
94
- export declare function createWidget(context: WidgetContext, registry?: Record<string, WidgetFactory>): Widget;
100
+ export declare function createWidget(given: WidgetContext, registry?: Record<string, WidgetFactory>): Widget;
95
101
  export declare function summary(value: Value | undefined, field: Field): string;
96
102
  export declare const builtInWidgets: Record<string, WidgetFactory>;
@@ -48,7 +48,9 @@ const payments_1 = require("./payments");
48
48
  * `type.widget` (such as `selection.radio`), then for the type alone. A type
49
49
  * with no editor yet shows its value read-only.
50
50
  */
51
- function createWidget(context, registry = {}) {
51
+ function createWidget(given, registry = given.widgets ?? {}) {
52
+ // The fields it draws of its own are found where it was.
53
+ const context = given.widgets === registry ? given : { ...given, widgets: registry };
52
54
  const { field, node } = context;
53
55
  const keys = [
54
56
  node.widget ? `${field.type}.${node.widget}` : null,
@@ -138,9 +140,11 @@ const NUMBER = /^-?(\d+\.?\d*|\.\d+)$/;
138
140
  const UNFINISHED = /^-?\.?$/;
139
141
  /**
140
142
  * Numbers are written as readers of the page's language write them, grouped,
141
- * with the field's decimals, and read back the same way. What is typed stays
142
- * as typed while focused: "1." means 1 now and 1.5 a keystroke later. The box
143
- * keeps its spelling when entered, so a selection made on the way in holds.
143
+ * with the field's decimals, and read back the same way. Entered, the box
144
+ * shows the plain number, no grouping marks — a digit typed mid-number would
145
+ * leave them in the wrong places ("600,1000.00") — and a whole-text selection
146
+ * made on the way in holds, so typing replaces it. What is typed stays as
147
+ * typed while focused: "1." means 1 now and 1.5 a keystroke later.
144
148
  */
145
149
  const numberWidget = (context) => {
146
150
  const { form, name, field, node, id, document, locale = 'en' } = context;
@@ -166,6 +170,21 @@ const numberWidget = (context) => {
166
170
  if (value !== undefined)
167
171
  form.setValue(name, value);
168
172
  });
173
+ input.addEventListener('focus', () => {
174
+ // Once the browser has put its selection in the box: a selection made before focus() is put back only after
175
+ // the focus event, and a click places its caret after it, against the plain words.
176
+ queueMicrotask(() => {
177
+ const value = form.getState().values[name];
178
+ if (document.activeElement !== input || input.readOnly || typeof value !== 'number' || input.value !== shown(value))
179
+ return;
180
+ const grouped = input.value;
181
+ const [start, end] = [input.selectionStart ?? grouped.length, input.selectionEnd ?? grouped.length];
182
+ // Where the selection stands among the digits, the grouping marks taken out.
183
+ const at = (index) => (0, numbers_1.ungroup)(grouped.slice(0, index), locale).length;
184
+ input.value = (0, numbers_1.ungroup)(grouped, locale);
185
+ input.setSelectionRange(at(start), at(end));
186
+ });
187
+ });
169
188
  input.addEventListener('blur', () => {
170
189
  input.value = shown(form.getState().values[name]);
171
190
  });
@@ -200,7 +219,8 @@ const numberWidget = (context) => {
200
219
  const parsed = parse(input.value);
201
220
  const showsSame = parsed === undefined || parsed === state.value;
202
221
  if (!(typing && showsSame)) {
203
- const text = shown(state.value);
222
+ // A value changed under the person editing it shows as they edit: plain.
223
+ const text = typing && !state.readonly && typeof state.value === 'number' ? (0, numbers_1.formatPlain)(state.value, decimals, locale) : shown(state.value);
204
224
  if (input.value !== text)
205
225
  input.value = text;
206
226
  }
@@ -249,7 +269,8 @@ const selectWidget = (context) => {
249
269
  if (search === true || (search !== false && options(field).length > 15))
250
270
  return (0, choice_tags_1.searchWidget)(context);
251
271
  const choices = (0, shuffle_1.shownOptions)(options(field), form, name, node);
252
- const select = make(document, 'select', { id, class: 'fd-input fd-select' }, make(document, 'option', { value: '' }));
272
+ const blank = make(document, 'option', { value: '' });
273
+ const select = make(document, 'select', { id, class: 'fd-input fd-select' }, blank);
253
274
  choices.forEach((option, i) => select.append(make(document, 'option', { value: String(i) }, option.label)));
254
275
  select.addEventListener('change', () => form.setValue(name, select.value === '' ? null : choices[Number(select.value)].value));
255
276
  return {
@@ -258,6 +279,8 @@ const selectWidget = (context) => {
258
279
  update(state) {
259
280
  const index = choices.findIndex((option) => option.value === state.value);
260
281
  select.value = index === -1 ? '' : String(index);
282
+ // A required choice made is never taken back to nothing from its list, as Flectra hides the blank.
283
+ blank.hidden = state.required && index !== -1;
261
284
  if (select.disabled !== state.readonly)
262
285
  select.disabled = state.readonly;
263
286
  describe(select, state);