@sylwellsoftware/fray 0.1.0-alpha.1 → 0.2.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 (44) hide show
  1. package/README.md +246 -11
  2. package/colors/README.md +15 -0
  3. package/colors/gray/colors.css +29 -0
  4. package/colors/green/colors.css +29 -0
  5. package/colors/iceblue/colors.css +29 -0
  6. package/colors/ocean/colors.css +29 -0
  7. package/colors/orange/colors.css +29 -0
  8. package/colors/purple/colors.css +29 -0
  9. package/colors/red/colors.css +29 -0
  10. package/colors/yellow/colors.css +29 -0
  11. package/dist/Components/data/table/DataTable.d.ts.map +1 -1
  12. package/dist/Components/data/table/TableHeaderCell.d.ts.map +1 -1
  13. package/dist/Components/dialog/dialog.d.ts.map +1 -1
  14. package/dist/Components/layout/panel.d.ts.map +1 -1
  15. package/dist/Components/layout/tabpanel/tabline.d.ts.map +1 -1
  16. package/dist/Components/lineinputs/checkbox/Checkbox.d.ts.map +1 -1
  17. package/dist/Components/lineinputs/toggle.d.ts.map +1 -1
  18. package/dist/Components/status/progressBar.d.ts.map +1 -1
  19. package/dist/Components/theme/stylesheetPicker.d.ts +40 -0
  20. package/dist/Components/theme/stylesheetPicker.d.ts.map +1 -0
  21. package/dist/{button-BRDkmR1C.js → button-CqDGmkBt.js} +87 -78
  22. package/dist/{button-BRDkmR1C.js.map → button-CqDGmkBt.js.map} +1 -1
  23. package/dist/experimental.js +104 -66
  24. package/dist/experimental.js.map +1 -1
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +801 -503
  28. package/dist/index.js.map +1 -1
  29. package/dist/{jsx-dev-runtime-CarwHDyL.js → jsx-dev-runtime-DukiDpV9.js} +202 -214
  30. package/dist/jsx-dev-runtime-DukiDpV9.js.map +1 -0
  31. package/dist/jsx-dev-runtime.js +1 -1
  32. package/dist/jsx-runtime.js +1 -1
  33. package/dist/styling/baseStyleDefinitions.d.ts +3 -0
  34. package/dist/styling/baseStyleDefinitions.d.ts.map +1 -1
  35. package/dist/styling/styleRegistry.d.ts.map +1 -1
  36. package/dist/styling/theme.d.ts +27 -0
  37. package/dist/styling/theme.d.ts.map +1 -0
  38. package/package.json +13 -5
  39. package/styles/structural.css +916 -0
  40. package/themes/README.md +84 -30
  41. package/themes/java/theme.css +140 -0
  42. package/themes/minimal/theme.css +128 -0
  43. package/themes/shiny/theme.css +314 -0
  44. package/dist/jsx-dev-runtime-CarwHDyL.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ import { Component } from '../component.js';
2
+ import type { FrayChild } from '../component.js';
3
+ import type { ValueControlProps, ValueEmitter } from '../controlUtils.js';
4
+ import type { FrayStylesheetKind, FrayStylesheetOption } from '../../styling/theme.js';
5
+ export interface StylesheetPickerProps extends ValueControlProps<string> {
6
+ id?: string | number | null;
7
+ label?: FrayChild;
8
+ ariaLabel?: string;
9
+ disabled?: boolean;
10
+ options?: readonly FrayStylesheetOption[];
11
+ targetDocument?: Document;
12
+ onChange?: (value: string, option: FrayStylesheetOption, event: Event) => void;
13
+ }
14
+ declare abstract class StylesheetPicker extends Component<StylesheetPickerProps> {
15
+ readonly valueEmitter: ValueEmitter<string>;
16
+ readonly inputId: string;
17
+ private readonly kind;
18
+ private readonly defaults;
19
+ constructor(props: StylesheetPickerProps, kind: FrayStylesheetKind, defaults: readonly FrayStylesheetOption[]);
20
+ initialize(): void;
21
+ render(): FrayChild;
22
+ afterMount(): void;
23
+ afterUpdate(): void;
24
+ protected get options(): readonly FrayStylesheetOption[];
25
+ private applySelection;
26
+ static baseStyles: (string | string[])[][];
27
+ static css: string;
28
+ }
29
+ export declare class ThemePicker extends StylesheetPicker {
30
+ constructor(props?: StylesheetPickerProps);
31
+ static hostName: string;
32
+ static standaloneHostName: string;
33
+ }
34
+ export declare class ColorPicker extends StylesheetPicker {
35
+ constructor(props?: StylesheetPickerProps);
36
+ static hostName: string;
37
+ static standaloneHostName: string;
38
+ }
39
+ export {};
40
+ //# sourceMappingURL=stylesheetPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stylesheetPicker.d.ts","sourceRoot":"","sources":["../../../src/Components/theme/stylesheetPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAM,MAAM,iBAAiB,CAAA;AAC9C,OAAO,KAAK,EAAiB,SAAS,EAAC,MAAM,iBAAiB,CAAA;AAO9D,OAAO,KAAK,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAOvE,OAAO,KAAK,EACR,kBAAkB,EAClB,oBAAoB,EACvB,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IACpE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACzC,cAAc,CAAC,EAAE,QAAQ,CAAA;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjF;AAED,uBAAe,gBAAiB,SAAQ,SAAS,CAAC,qBAAqB,CAAC;IACpE,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;gBAGtD,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,kBAAkB,EACxB,QAAQ,EAAE,SAAS,oBAAoB,EAAE;IAc7C,UAAU,IAAI,IAAI;IAIlB,MAAM,IAAI,SAAS;IAiCnB,UAAU,IAAI,IAAI;IAIlB,WAAW,IAAI,IAAI;IAInB,SAAS,KAAK,OAAO,IAAI,SAAS,oBAAoB,EAAE,CAIvD;IAED,OAAO,CAAC,cAAc;IAWtB,MAAM,CAAC,UAAU,0BAKhB;IAED,MAAM,CAAC,GAAG,SAQT;CACJ;AAED,qBAAa,WAAY,SAAQ,gBAAgB;gBACjC,KAAK,GAAE,qBAA0B;IAI7C,OAAgB,QAAQ,SAAiB;IACzC,OAAgB,kBAAkB,SAAiB;CACtD;AAED,qBAAa,WAAY,SAAQ,gBAAgB;gBACjC,KAAK,GAAE,qBAA0B;IAI7C,OAAgB,QAAQ,SAAiB;IACzC,OAAgB,kBAAkB,SAAiB;CACtD"}
@@ -1,26 +1,26 @@
1
1
  var N = Object.defineProperty;
2
- var I = (e, t, n) => t in e ? N(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
- var i = (e, t, n) => I(e, typeof t != "symbol" ? t + "" : t, n);
4
- import { C as w, j as h, c as E, a as T } from "./jsx-dev-runtime-CarwHDyL.js";
2
+ var I = (e, t, a) => t in e ? N(e, t, { enumerable: !0, configurable: !0, writable: !0, value: a }) : e[t] = a;
3
+ var n = (e, t, a) => I(e, typeof t != "symbol" ? t + "" : t, a);
4
+ import { C as k, j as y, c as x, a as T } from "./jsx-dev-runtime-DukiDpV9.js";
5
5
  import { Emitter as V } from "@sylwellsoftware/glue";
6
6
  let j = 1;
7
7
  function B(e, t) {
8
8
  return t != null && String(t).length > 0 ? String(t) : `fray-${e}-${j++}`;
9
9
  }
10
- function q(e, t, n, r) {
10
+ function q(e, t, a, i) {
11
11
  if (t.valueEmitter != null)
12
12
  return R(t.valueEmitter, "valueEmitter"), t.valueEmitter;
13
- const s = t.defaultValue ?? t.value ?? t.initialValue ?? n, l = { owner: e, purpose: r };
14
- return new V(s, l);
13
+ const s = t.defaultValue ?? t.value ?? t.initialValue ?? a, o = { owner: e, purpose: i };
14
+ return new V(s, o);
15
15
  }
16
16
  function R(e, t = "emitter") {
17
17
  if (e == null || typeof e != "object" && typeof e != "function" || typeof Reflect.get(e, "get") != "function" || typeof Reflect.get(e, "set") != "function" || typeof Reflect.get(e, "subscribe") != "function")
18
18
  throw new TypeError(`${t} must be an emitter`);
19
19
  }
20
- function x(e) {
20
+ function w(e) {
21
21
  return e.className ?? e.class ?? "";
22
22
  }
23
- function k(e, ...t) {
23
+ function E(e, ...t) {
24
24
  if (e != null) {
25
25
  if (typeof e != "function") throw new TypeError("Control callback must be a function");
26
26
  e(...t);
@@ -32,7 +32,7 @@ function F(e, t = "options") {
32
32
  function $(e) {
33
33
  return e === "" ? "prefer" : e === "!" ? "deny" : e === "_" ? "require" : e === "☐" ? "neutral" : String(e);
34
34
  }
35
- const f = {
35
+ const b = {
36
36
  /** Deny mode: Excludes items that match the filter. */
37
37
  Deny: "!",
38
38
  /** Require mode: Includes only items that match the filter. */
@@ -42,18 +42,18 @@ const f = {
42
42
  /** Neutral mode: Does not affect the inclusion or exclusion of items. */
43
43
  Neutral: "☐"
44
44
  };
45
- class u extends w {
46
- constructor(n = {}) {
47
- super(n);
48
- i(this, "symbols");
49
- i(this, "valueEmitter");
50
- i(this, "semanticStateEmitter");
51
- const r = this.constructor;
52
- this.symbols = n.symbols ?? r.symbols, D(this.symbols);
53
- const s = n.initialSemanticState ?? r.defaultSemanticState ?? this.symbols[0][1], l = { ...n };
54
- l.defaultValue == null && n.initialSemanticState != null && (l.defaultValue = n.initialSemanticState), this.valueEmitter = q(
45
+ class u extends k {
46
+ constructor(a = {}) {
47
+ super(a);
48
+ n(this, "symbols");
49
+ n(this, "valueEmitter");
50
+ n(this, "semanticStateEmitter");
51
+ const i = this.constructor;
52
+ this.symbols = a.symbols ?? i.symbols, D(this.symbols);
53
+ const s = a.initialSemanticState ?? i.defaultSemanticState ?? this.symbols[0][1], o = { ...a };
54
+ o.defaultValue == null && a.initialSemanticState != null && (o.defaultValue = a.initialSemanticState), this.valueEmitter = q(
55
55
  this,
56
- l,
56
+ o,
57
57
  s,
58
58
  "checkbox semantic state"
59
59
  ), this.semanticStateEmitter = this.valueEmitter;
@@ -61,45 +61,45 @@ class u extends w {
61
61
  initialize() {
62
62
  this.watch(this.valueEmitter);
63
63
  }
64
- cycleState(n = 1, r = null) {
64
+ cycleState(a = 1, i = null) {
65
65
  if (this.props.disabled) return;
66
- const s = this.symbols.findIndex(([, d]) => Object.is(d, this.valueEmitter.get())), c = ((s < 0 ? 0 : s) + n + this.symbols.length) % this.symbols.length, o = this.symbols[c][1];
67
- this.valueEmitter.set(o, "checkbox state changed"), k(this.props.onChange, o, r);
66
+ const s = this.symbols.findIndex(([, d]) => Object.is(d, this.valueEmitter.get())), c = ((s < 0 ? 0 : s) + a + this.symbols.length) % this.symbols.length, l = this.symbols[c][1];
67
+ this.valueEmitter.set(l, "checkbox state changed"), E(this.props.onChange, l, i);
68
68
  }
69
69
  render() {
70
70
  const {
71
- label: n = this.props.value ?? "Option",
72
- disabled: r = !1,
71
+ label: a = this.props.value ?? "Option",
72
+ disabled: i = !1,
73
73
  required: s = !1,
74
- name: l,
74
+ name: o,
75
75
  value: c
76
- } = this.props, o = this.valueEmitter.get(), [d] = this.symbols.find(([, a]) => Object.is(a, o)) ?? ["?", o], m = $(o), b = o === f.Prefer || o === f.Require, y = this.Host;
77
- return /* @__PURE__ */ h(
78
- y,
76
+ } = this.props, l = this.valueEmitter.get(), [d] = this.symbols.find(([, r]) => Object.is(r, l)) ?? ["?", l], f = $(l), m = l === b.Prefer || l === b.Require, h = this.Host;
77
+ return /* @__PURE__ */ y(
78
+ h,
79
79
  {
80
- className: x(this.props) || null,
81
- "data-disabled": r ? "" : null,
80
+ className: w(this.props) || null,
81
+ "data-disabled": i ? "" : null,
82
82
  "data-required": s ? "" : null,
83
- "data-state": m,
83
+ "data-state": f,
84
84
  children: /* @__PURE__ */ T(
85
85
  "button",
86
86
  {
87
87
  type: "button",
88
88
  role: "checkbox",
89
- disabled: r,
90
- name: l,
89
+ disabled: i,
90
+ name: o,
91
91
  value: c == null ? void 0 : String(c),
92
92
  "data-part": "control",
93
- "aria-checked": b ? "true" : "false",
93
+ "aria-checked": m ? "true" : "false",
94
94
  "aria-required": s ? "true" : null,
95
- "aria-label": `${n}: ${m}`,
96
- onClick: (a) => this.cycleState(1, a),
97
- onKeyDown: (a) => {
98
- a.key === "ArrowRight" || a.key === "ArrowDown" ? (a.preventDefault(), this.cycleState(1, a)) : (a.key === "ArrowLeft" || a.key === "ArrowUp") && (a.preventDefault(), this.cycleState(-1, a));
95
+ "aria-label": `${a}: ${f}`,
96
+ onClick: (r) => this.cycleState(1, r),
97
+ onKeyDown: (r) => {
98
+ r.key === "ArrowRight" || r.key === "ArrowDown" ? (r.preventDefault(), this.cycleState(1, r)) : (r.key === "ArrowLeft" || r.key === "ArrowUp") && (r.preventDefault(), this.cycleState(-1, r));
99
99
  },
100
100
  children: [
101
- /* @__PURE__ */ h("span", { "data-part": "symbol", "aria-hidden": "true", children: d }),
102
- /* @__PURE__ */ h("span", { "data-part": "label", children: n })
101
+ /* @__PURE__ */ y("span", { "data-part": "symbol", "aria-hidden": "true", children: d }),
102
+ /* @__PURE__ */ y("span", { "data-part": "label", children: a })
103
103
  ]
104
104
  }
105
105
  )
@@ -107,14 +107,14 @@ class u extends w {
107
107
  );
108
108
  }
109
109
  }
110
- i(u, "symbols", [
111
- ["☐", f.Neutral],
112
- ["✓", f.Prefer]
113
- ]), i(u, "defaultSemanticState", f.Neutral), i(u, "hostName", "checkbox"), i(u, "standaloneHostName", "check-box"), i(u, "baseStyles", [
110
+ n(u, "symbols", [
111
+ ["☐", b.Neutral],
112
+ ["✓", b.Prefer]
113
+ ]), n(u, "defaultSemanticState", b.Neutral), n(u, "hostName", "checkbox"), n(u, "standaloneHostName", "check-box"), n(u, "baseStyles", [
114
114
  ["&", ["inputline"]],
115
115
  ['& > [data-part="control"]', ["input", "inputline"]],
116
116
  ["&[data-disabled]", ["disabled"]]
117
- ]), i(u, "css", E`
117
+ ]), n(u, "css", x`
118
118
  & > [data-part="control"] {
119
119
  display: inline-flex;
120
120
  align-items: center;
@@ -129,8 +129,17 @@ i(u, "symbols", [
129
129
  height: 1em;
130
130
  line-height: 1;
131
131
  place-items: center;
132
- border: var(--cbx-o-border, 1px solid currentColor);
133
- border-radius: var(--cbx-border-radius, var(--ui-border-radius));
132
+ color: var(--fray-checkbox-symbol-color, currentColor);
133
+ background: var(--fray-checkbox-box-background, transparent);
134
+ border: var(--fray-checkbox-box-border, var(--cbx-o-border));
135
+ border-radius: var(--cbx-border-radius, var(--fray-radius-sm));
136
+ }
137
+
138
+ & [data-part="control"][aria-checked="true"] [data-part="symbol"] {
139
+ background: var(
140
+ --fray-checkbox-box-background-checked,
141
+ var(--fray-selection-background)
142
+ );
134
143
  }
135
144
  `);
136
145
  function D(e) {
@@ -140,7 +149,7 @@ function D(e) {
140
149
  if (!Array.isArray(t) || t.length < 2)
141
150
  throw new TypeError("Checkbox symbols must be [symbol, state] tuples");
142
151
  }
143
- class g extends w {
152
+ class S extends k {
144
153
  constructor(t = {}) {
145
154
  if (super(t), t.onClick != null && typeof t.onClick != "function")
146
155
  throw new TypeError("Button onClick must be a function");
@@ -148,56 +157,56 @@ class g extends w {
148
157
  render() {
149
158
  const {
150
159
  children: t = [],
151
- label: n,
152
- type: r = "button",
160
+ label: a,
161
+ type: i = "button",
153
162
  disabled: s = !1,
154
- pressed: l,
163
+ pressed: o,
155
164
  busy: c = !1,
156
- busyLabel: o,
165
+ busyLabel: l,
157
166
  id: d,
158
- name: m,
159
- value: b,
160
- title: y,
161
- ariaLabel: a,
162
- onClick: C
163
- } = this.props, p = (Array.isArray(t) ? t.length > 0 : t != null && typeof t != "boolean") ? t : n ?? "", A = c ? o ?? p : p, S = s || c;
164
- return /* @__PURE__ */ h(
167
+ name: f,
168
+ value: m,
169
+ title: h,
170
+ ariaLabel: r,
171
+ onClick: v
172
+ } = this.props, p = (Array.isArray(t) ? t.length > 0 : t != null && typeof t != "boolean") ? t : a ?? "", C = c ? l ?? p : p, g = s || c;
173
+ return /* @__PURE__ */ y(
165
174
  "button",
166
175
  {
167
176
  id: d,
168
- name: m,
169
- value: b == null ? void 0 : String(b),
170
- title: y,
171
- type: r,
172
- disabled: S,
173
- className: x(this.props) || void 0,
177
+ name: f,
178
+ value: m == null ? void 0 : String(m),
179
+ title: h,
180
+ type: i,
181
+ disabled: g,
182
+ className: w(this.props) || void 0,
174
183
  "data-fray-component": "button",
175
- "aria-label": a,
176
- "aria-pressed": l == null ? null : String(!!l),
184
+ "aria-label": r,
185
+ "aria-pressed": o == null ? null : String(!!o),
177
186
  "aria-busy": c ? "true" : null,
178
- onClick: (v) => {
179
- S || k(C, v);
187
+ onClick: (A) => {
188
+ g || E(v, A);
180
189
  },
181
- children: A
190
+ children: C
182
191
  }
183
192
  );
184
193
  }
185
194
  }
186
- i(g, "baseStyles", [
195
+ n(S, "baseStyles", [
187
196
  ['button[data-fray-component="button"]', ["uiline", "button"]]
188
- ]), i(g, "css", E`
197
+ ]), n(S, "css", x`
189
198
  button[data-fray-component="button"] {
190
199
  font-family: inherit;
191
200
  }
192
201
  `);
193
202
  export {
194
- g as B,
203
+ S as B,
195
204
  u as C,
196
- f as F,
205
+ b as F,
197
206
  q as a,
198
207
  B as b,
199
- x as c,
208
+ w as c,
200
209
  F as d,
201
- k as i
210
+ E as i
202
211
  };
203
- //# sourceMappingURL=button-BRDkmR1C.js.map
212
+ //# sourceMappingURL=button-CqDGmkBt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-BRDkmR1C.js","sources":["../src/Components/controlUtils.ts","../src/util/filterMode.ts","../src/Components/lineinputs/checkbox/Checkbox.tsx","../src/Components/menu/button.tsx"],"sourcesContent":["import {Emitter} from '@sylwellsoftware/glue'\nimport type {EmitterOptions, ReadableEmitter} from '@sylwellsoftware/glue'\n\nimport type {Component, ComponentProps} from './component.js'\n\nexport interface ValueEmitter<TValue> extends ReadableEmitter<TValue, unknown> {\n set(value: TValue, eventOrCause?: unknown): boolean\n}\n\nexport interface ValueControlProps<TValue> extends ComponentProps {\n valueEmitter?: ValueEmitter<TValue>\n value?: TValue\n defaultValue?: TValue\n initialValue?: TValue\n}\n\nlet nextControlId = 1\n\nexport function controlId(prefix: string, provided?: string | number | null): string {\n if (provided != null && String(provided).length > 0) return String(provided)\n return `fray-${prefix}-${nextControlId++}`\n}\n\nexport function createValueEmitter<TValue>(\n component: Component,\n props: ValueControlProps<TValue>,\n fallback: TValue,\n purpose: string,\n): ValueEmitter<TValue> {\n if (props.valueEmitter != null) {\n assertEmitter<TValue>(props.valueEmitter, 'valueEmitter')\n return props.valueEmitter\n }\n const initialValue = props.defaultValue\n ?? props.value\n ?? props.initialValue\n ?? fallback\n const options: EmitterOptions<TValue> = {owner: component, purpose}\n return new Emitter(initialValue, options)\n}\n\nexport function assertEmitter<TValue = unknown>(\n value: unknown,\n name = 'emitter',\n): asserts value is ValueEmitter<TValue> {\n if (value == null\n || (typeof value !== 'object' && typeof value !== 'function')\n || typeof Reflect.get(value, 'get') !== 'function'\n || typeof Reflect.get(value, 'set') !== 'function'\n || typeof Reflect.get(value, 'subscribe') !== 'function') {\n throw new TypeError(`${name} must be an emitter`)\n }\n}\n\nexport function classNames(...values: unknown[]): string {\n return values\n .flatMap((value) => typeof value === 'string' ? value.split(/\\s+/) : [])\n .filter(Boolean)\n .join(' ')\n}\n\nexport function componentClass(props: Pick<ComponentProps, 'class' | 'className'>): string {\n return props.className ?? props.class ?? ''\n}\n\nexport function invoke<TArguments extends unknown[]>(\n callback: ((...args: TArguments) => void) | null | undefined,\n ...args: TArguments\n): void {\n if (callback == null) return\n if (typeof callback !== 'function') throw new TypeError('Control callback must be a function')\n callback(...args)\n}\n\nexport function assertOptions<TOption>(\n options: unknown,\n name = 'options',\n): asserts options is TOption[] {\n if (!Array.isArray(options)) throw new TypeError(`${name} must be an array`)\n}\n\nexport function describeState(value: unknown): string {\n if (value === '') return 'prefer'\n if (value === '!') return 'deny'\n if (value === '_') return 'require'\n if (value === '☐') return 'neutral'\n return String(value)\n}\n","/** Represents the filter mode for a query. */\nexport const FilterMode = {\n /** Deny mode: Excludes items that match the filter. */\n Deny: '!',\n /** Require mode: Includes only items that match the filter. */\n Require: '_',\n /** Prefer mode: If there are any filter options that are set to Prefer, at least one of the preferred filter options must match. Otherwise, it is treated as Neutral. */\n Prefer: '',\n /** Neutral mode: Does not affect the inclusion or exclusion of items. */\n Neutral: '☐',\n} as const\n\nexport type FilterModeValue = typeof FilterMode[keyof typeof FilterMode]\n","import {Component, css} from '../../component.js'\nimport type {ComponentProps, FrayChild} from '../../component.js'\nimport {\n componentClass,\n createValueEmitter,\n describeState,\n invoke,\n} from '../../controlUtils.js'\nimport type {ValueControlProps, ValueEmitter} from '../../controlUtils.js'\nimport {FilterMode} from '../../../util/filterMode.js'\nimport type {FilterModeValue} from '../../../util/filterMode.js'\n\nexport type CheckboxValue = string | number\nexport type CheckboxSymbol<TValue extends CheckboxValue = FilterModeValue> = readonly [\n symbol: FrayChild,\n value: TValue,\n]\n\nexport interface CheckboxProps<TValue extends CheckboxValue = FilterModeValue>\n extends ValueControlProps<TValue> {\n symbols?: readonly CheckboxSymbol<TValue>[]\n initialSemanticState?: TValue\n label?: FrayChild\n disabled?: boolean\n required?: boolean\n name?: string\n onChange?: (value: TValue, event: Event | null) => void\n}\n\n/** Keyboard-operable semantic state cycler. */\nexport class Checkbox<TValue extends CheckboxValue = FilterModeValue>\n extends Component<CheckboxProps<TValue>> {\n static symbols: readonly CheckboxSymbol<FilterModeValue>[] = [\n ['☐', FilterMode.Neutral],\n ['✓', FilterMode.Prefer],\n ]\n static defaultSemanticState = FilterMode.Neutral\n\n readonly symbols: readonly CheckboxSymbol<TValue>[]\n readonly valueEmitter: ValueEmitter<TValue>\n readonly semanticStateEmitter: ValueEmitter<TValue>\n\n constructor(props: CheckboxProps<TValue> = {}) {\n super(props)\n const componentType = this.constructor as typeof Checkbox\n // Static members cannot carry the instance's generic state parameter;\n // subclasses validate the tuple values before this boundary is used.\n this.symbols = props.symbols\n ?? componentType.symbols as unknown as readonly CheckboxSymbol<TValue>[]\n validateSymbols(this.symbols)\n const fallback = props.initialSemanticState\n ?? componentType.defaultSemanticState as TValue\n ?? this.symbols[0]![1]\n const emitterProps: CheckboxProps<TValue> = {...props}\n if (emitterProps.defaultValue == null && props.initialSemanticState != null) {\n emitterProps.defaultValue = props.initialSemanticState\n }\n this.valueEmitter = createValueEmitter<TValue>(this, emitterProps, fallback,\n 'checkbox semantic state')\n // Compatibility alias used only by the experimental filter implementation.\n this.semanticStateEmitter = this.valueEmitter\n }\n\n initialize(): void {\n this.watch(this.valueEmitter)\n }\n\n cycleState(direction = 1, event: Event | null = null): void {\n if (this.props.disabled) return\n const currentIndex = this.symbols.findIndex(([, state]) =>\n Object.is(state, this.valueEmitter.get()))\n const baseIndex = currentIndex < 0 ? 0 : currentIndex\n const nextIndex = (baseIndex + direction + this.symbols.length) % this.symbols.length\n const nextValue = this.symbols[nextIndex]![1]\n this.valueEmitter.set(nextValue, 'checkbox state changed')\n invoke(this.props.onChange, nextValue, event)\n }\n\n render(): FrayChild {\n const {\n label = this.props.value ?? 'Option',\n disabled = false,\n required = false,\n name,\n value,\n } = this.props\n const semanticState = this.valueEmitter.get()\n const [symbol] = this.symbols.find(([, state]) => Object.is(state, semanticState))\n ?? ['?', semanticState]\n const stateName = describeState(semanticState)\n const checked = semanticState === FilterMode.Prefer\n || semanticState === FilterMode.Require\n\n const Host = this.Host\n return <Host\n className={componentClass(this.props) || null}\n data-disabled={disabled ? '' : null}\n data-required={required ? '' : null}\n data-state={stateName}\n >\n <button\n type=\"button\"\n role=\"checkbox\"\n disabled={disabled}\n name={name}\n value={value == null ? undefined : String(value)}\n data-part=\"control\"\n aria-checked={checked ? 'true' : 'false'}\n aria-required={required ? 'true' : null}\n aria-label={`${label}: ${stateName}`}\n onClick={(event: MouseEvent) => this.cycleState(1, event)}\n onKeyDown={(event: KeyboardEvent) => {\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault()\n this.cycleState(1, event)\n } else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault()\n this.cycleState(-1, event)\n }\n }}\n >\n <span data-part=\"symbol\" aria-hidden=\"true\">{symbol}</span>\n <span data-part=\"label\">{label}</span>\n </button>\n </Host>\n }\n\n static override hostName = 'checkbox'\n static override standaloneHostName = 'check-box'\n\n static baseStyles = [\n ['&', ['inputline']],\n ['& > [data-part=\"control\"]', ['input', 'inputline']],\n ['&[data-disabled]', ['disabled']],\n ]\n\n static css = css`\n & > [data-part=\"control\"] {\n display: inline-flex;\n align-items: center;\n gap: 0.35em;\n width: auto;\n font-family: inherit;\n }\n\n & [data-part=\"symbol\"] {\n display: inline-grid;\n width: 1em;\n height: 1em;\n line-height: 1;\n place-items: center;\n border: var(--cbx-o-border, 1px solid currentColor);\n border-radius: var(--cbx-border-radius, var(--ui-border-radius));\n }\n `\n}\n\nfunction validateSymbols<TValue extends CheckboxValue>(\n symbols: unknown,\n): asserts symbols is readonly CheckboxSymbol<TValue>[] {\n if (!Array.isArray(symbols) || symbols.length === 0) {\n throw new TypeError('Checkbox symbols must be a non-empty tuple array')\n }\n for (const tuple of symbols) {\n if (!Array.isArray(tuple) || tuple.length < 2) {\n throw new TypeError('Checkbox symbols must be [symbol, state] tuples')\n }\n }\n}\n","import {Component, css} from '../component.js'\nimport type {ComponentProps, FrayChild} from '../component.js'\nimport {componentClass, invoke} from '../controlUtils.js'\n\nexport interface ButtonProps extends ComponentProps {\n label?: FrayChild\n type?: 'button' | 'reset' | 'submit'\n disabled?: boolean\n pressed?: boolean\n busy?: boolean\n busyLabel?: FrayChild\n id?: string\n name?: string\n value?: string | number\n title?: string\n ariaLabel?: string\n onClick?: (event: MouseEvent) => void\n}\n\n/** Native actionable button primitive. */\nexport class Button extends Component<ButtonProps> {\n constructor(props: ButtonProps = {}) {\n super(props)\n if (props.onClick != null && typeof props.onClick !== 'function') {\n throw new TypeError('Button onClick must be a function')\n }\n }\n\n render(): FrayChild {\n const {\n children = [],\n label,\n type = 'button',\n disabled = false,\n pressed,\n busy = false,\n busyLabel,\n id,\n name,\n value,\n title,\n ariaLabel,\n onClick,\n } = this.props\n const hasChildren = Array.isArray(children)\n ? children.length > 0\n : children != null && typeof children !== 'boolean'\n const normalContent = hasChildren ? children : (label ?? '')\n const content = busy ? (busyLabel ?? normalContent) : normalContent\n const unavailable = disabled || busy\n\n return <button\n id={id}\n name={name}\n value={value == null ? undefined : String(value)}\n title={title}\n type={type}\n disabled={unavailable}\n className={componentClass(this.props) || undefined}\n data-fray-component=\"button\"\n aria-label={ariaLabel}\n aria-pressed={pressed == null ? null : String(Boolean(pressed))}\n aria-busy={busy ? 'true' : null}\n onClick={(event: MouseEvent) => {\n if (!unavailable) invoke(onClick, event)\n }}\n >{content}</button>\n }\n\n static baseStyles = [\n ['button[data-fray-component=\"button\"]', ['uiline', 'button']],\n ]\n\n static css = css`\n button[data-fray-component=\"button\"] {\n font-family: inherit;\n }\n `\n}\n"],"names":["nextControlId","controlId","prefix","provided","createValueEmitter","component","props","fallback","purpose","assertEmitter","initialValue","options","Emitter","value","name","componentClass","invoke","callback","args","assertOptions","describeState","FilterMode","Checkbox","Component","__publicField","componentType","validateSymbols","emitterProps","direction","event","currentIndex","state","nextIndex","nextValue","label","disabled","required","semanticState","symbol","stateName","checked","Host","jsx","jsxs","css","symbols","tuple","Button","children","type","pressed","busy","busyLabel","id","title","ariaLabel","onClick","normalContent","content","unavailable"],"mappings":"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"}
1
+ {"version":3,"file":"button-CqDGmkBt.js","sources":["../src/Components/controlUtils.ts","../src/util/filterMode.ts","../src/Components/lineinputs/checkbox/Checkbox.tsx","../src/Components/menu/button.tsx"],"sourcesContent":["import {Emitter} from '@sylwellsoftware/glue'\nimport type {EmitterOptions, ReadableEmitter} from '@sylwellsoftware/glue'\n\nimport type {Component, ComponentProps} from './component.js'\n\nexport interface ValueEmitter<TValue> extends ReadableEmitter<TValue, unknown> {\n set(value: TValue, eventOrCause?: unknown): boolean\n}\n\nexport interface ValueControlProps<TValue> extends ComponentProps {\n valueEmitter?: ValueEmitter<TValue>\n value?: TValue\n defaultValue?: TValue\n initialValue?: TValue\n}\n\nlet nextControlId = 1\n\nexport function controlId(prefix: string, provided?: string | number | null): string {\n if (provided != null && String(provided).length > 0) return String(provided)\n return `fray-${prefix}-${nextControlId++}`\n}\n\nexport function createValueEmitter<TValue>(\n component: Component,\n props: ValueControlProps<TValue>,\n fallback: TValue,\n purpose: string,\n): ValueEmitter<TValue> {\n if (props.valueEmitter != null) {\n assertEmitter<TValue>(props.valueEmitter, 'valueEmitter')\n return props.valueEmitter\n }\n const initialValue = props.defaultValue\n ?? props.value\n ?? props.initialValue\n ?? fallback\n const options: EmitterOptions<TValue> = {owner: component, purpose}\n return new Emitter(initialValue, options)\n}\n\nexport function assertEmitter<TValue = unknown>(\n value: unknown,\n name = 'emitter',\n): asserts value is ValueEmitter<TValue> {\n if (value == null\n || (typeof value !== 'object' && typeof value !== 'function')\n || typeof Reflect.get(value, 'get') !== 'function'\n || typeof Reflect.get(value, 'set') !== 'function'\n || typeof Reflect.get(value, 'subscribe') !== 'function') {\n throw new TypeError(`${name} must be an emitter`)\n }\n}\n\nexport function classNames(...values: unknown[]): string {\n return values\n .flatMap((value) => typeof value === 'string' ? value.split(/\\s+/) : [])\n .filter(Boolean)\n .join(' ')\n}\n\nexport function componentClass(props: Pick<ComponentProps, 'class' | 'className'>): string {\n return props.className ?? props.class ?? ''\n}\n\nexport function invoke<TArguments extends unknown[]>(\n callback: ((...args: TArguments) => void) | null | undefined,\n ...args: TArguments\n): void {\n if (callback == null) return\n if (typeof callback !== 'function') throw new TypeError('Control callback must be a function')\n callback(...args)\n}\n\nexport function assertOptions<TOption>(\n options: unknown,\n name = 'options',\n): asserts options is TOption[] {\n if (!Array.isArray(options)) throw new TypeError(`${name} must be an array`)\n}\n\nexport function describeState(value: unknown): string {\n if (value === '') return 'prefer'\n if (value === '!') return 'deny'\n if (value === '_') return 'require'\n if (value === '☐') return 'neutral'\n return String(value)\n}\n","/** Represents the filter mode for a query. */\nexport const FilterMode = {\n /** Deny mode: Excludes items that match the filter. */\n Deny: '!',\n /** Require mode: Includes only items that match the filter. */\n Require: '_',\n /** Prefer mode: If there are any filter options that are set to Prefer, at least one of the preferred filter options must match. Otherwise, it is treated as Neutral. */\n Prefer: '',\n /** Neutral mode: Does not affect the inclusion or exclusion of items. */\n Neutral: '☐',\n} as const\n\nexport type FilterModeValue = typeof FilterMode[keyof typeof FilterMode]\n","import {Component, css} from '../../component.js'\nimport type {ComponentProps, FrayChild} from '../../component.js'\nimport {\n componentClass,\n createValueEmitter,\n describeState,\n invoke,\n} from '../../controlUtils.js'\nimport type {ValueControlProps, ValueEmitter} from '../../controlUtils.js'\nimport {FilterMode} from '../../../util/filterMode.js'\nimport type {FilterModeValue} from '../../../util/filterMode.js'\n\nexport type CheckboxValue = string | number\nexport type CheckboxSymbol<TValue extends CheckboxValue = FilterModeValue> = readonly [\n symbol: FrayChild,\n value: TValue,\n]\n\nexport interface CheckboxProps<TValue extends CheckboxValue = FilterModeValue>\n extends ValueControlProps<TValue> {\n symbols?: readonly CheckboxSymbol<TValue>[]\n initialSemanticState?: TValue\n label?: FrayChild\n disabled?: boolean\n required?: boolean\n name?: string\n onChange?: (value: TValue, event: Event | null) => void\n}\n\n/** Keyboard-operable semantic state cycler. */\nexport class Checkbox<TValue extends CheckboxValue = FilterModeValue>\n extends Component<CheckboxProps<TValue>> {\n static symbols: readonly CheckboxSymbol<FilterModeValue>[] = [\n ['☐', FilterMode.Neutral],\n ['✓', FilterMode.Prefer],\n ]\n static defaultSemanticState = FilterMode.Neutral\n\n readonly symbols: readonly CheckboxSymbol<TValue>[]\n readonly valueEmitter: ValueEmitter<TValue>\n readonly semanticStateEmitter: ValueEmitter<TValue>\n\n constructor(props: CheckboxProps<TValue> = {}) {\n super(props)\n const componentType = this.constructor as typeof Checkbox\n // Static members cannot carry the instance's generic state parameter;\n // subclasses validate the tuple values before this boundary is used.\n this.symbols = props.symbols\n ?? componentType.symbols as unknown as readonly CheckboxSymbol<TValue>[]\n validateSymbols(this.symbols)\n const fallback = props.initialSemanticState\n ?? componentType.defaultSemanticState as TValue\n ?? this.symbols[0]![1]\n const emitterProps: CheckboxProps<TValue> = {...props}\n if (emitterProps.defaultValue == null && props.initialSemanticState != null) {\n emitterProps.defaultValue = props.initialSemanticState\n }\n this.valueEmitter = createValueEmitter<TValue>(this, emitterProps, fallback,\n 'checkbox semantic state')\n // Compatibility alias used only by the experimental filter implementation.\n this.semanticStateEmitter = this.valueEmitter\n }\n\n initialize(): void {\n this.watch(this.valueEmitter)\n }\n\n cycleState(direction = 1, event: Event | null = null): void {\n if (this.props.disabled) return\n const currentIndex = this.symbols.findIndex(([, state]) =>\n Object.is(state, this.valueEmitter.get()))\n const baseIndex = currentIndex < 0 ? 0 : currentIndex\n const nextIndex = (baseIndex + direction + this.symbols.length) % this.symbols.length\n const nextValue = this.symbols[nextIndex]![1]\n this.valueEmitter.set(nextValue, 'checkbox state changed')\n invoke(this.props.onChange, nextValue, event)\n }\n\n render(): FrayChild {\n const {\n label = this.props.value ?? 'Option',\n disabled = false,\n required = false,\n name,\n value,\n } = this.props\n const semanticState = this.valueEmitter.get()\n const [symbol] = this.symbols.find(([, state]) => Object.is(state, semanticState))\n ?? ['?', semanticState]\n const stateName = describeState(semanticState)\n const checked = semanticState === FilterMode.Prefer\n || semanticState === FilterMode.Require\n\n const Host = this.Host\n return <Host\n className={componentClass(this.props) || null}\n data-disabled={disabled ? '' : null}\n data-required={required ? '' : null}\n data-state={stateName}\n >\n <button\n type=\"button\"\n role=\"checkbox\"\n disabled={disabled}\n name={name}\n value={value == null ? undefined : String(value)}\n data-part=\"control\"\n aria-checked={checked ? 'true' : 'false'}\n aria-required={required ? 'true' : null}\n aria-label={`${label}: ${stateName}`}\n onClick={(event: MouseEvent) => this.cycleState(1, event)}\n onKeyDown={(event: KeyboardEvent) => {\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault()\n this.cycleState(1, event)\n } else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault()\n this.cycleState(-1, event)\n }\n }}\n >\n <span data-part=\"symbol\" aria-hidden=\"true\">{symbol}</span>\n <span data-part=\"label\">{label}</span>\n </button>\n </Host>\n }\n\n static override hostName = 'checkbox'\n static override standaloneHostName = 'check-box'\n\n static baseStyles = [\n ['&', ['inputline']],\n ['& > [data-part=\"control\"]', ['input', 'inputline']],\n ['&[data-disabled]', ['disabled']],\n ]\n\n static css = css`\n & > [data-part=\"control\"] {\n display: inline-flex;\n align-items: center;\n gap: 0.35em;\n width: auto;\n font-family: inherit;\n }\n\n & [data-part=\"symbol\"] {\n display: inline-grid;\n width: 1em;\n height: 1em;\n line-height: 1;\n place-items: center;\n color: var(--fray-checkbox-symbol-color, currentColor);\n background: var(--fray-checkbox-box-background, transparent);\n border: var(--fray-checkbox-box-border, var(--cbx-o-border));\n border-radius: var(--cbx-border-radius, var(--fray-radius-sm));\n }\n\n & [data-part=\"control\"][aria-checked=\"true\"] [data-part=\"symbol\"] {\n background: var(\n --fray-checkbox-box-background-checked,\n var(--fray-selection-background)\n );\n }\n `\n}\n\nfunction validateSymbols<TValue extends CheckboxValue>(\n symbols: unknown,\n): asserts symbols is readonly CheckboxSymbol<TValue>[] {\n if (!Array.isArray(symbols) || symbols.length === 0) {\n throw new TypeError('Checkbox symbols must be a non-empty tuple array')\n }\n for (const tuple of symbols) {\n if (!Array.isArray(tuple) || tuple.length < 2) {\n throw new TypeError('Checkbox symbols must be [symbol, state] tuples')\n }\n }\n}\n","import {Component, css} from '../component.js'\nimport type {ComponentProps, FrayChild} from '../component.js'\nimport {componentClass, invoke} from '../controlUtils.js'\n\nexport interface ButtonProps extends ComponentProps {\n label?: FrayChild\n type?: 'button' | 'reset' | 'submit'\n disabled?: boolean\n pressed?: boolean\n busy?: boolean\n busyLabel?: FrayChild\n id?: string\n name?: string\n value?: string | number\n title?: string\n ariaLabel?: string\n onClick?: (event: MouseEvent) => void\n}\n\n/** Native actionable button primitive. */\nexport class Button extends Component<ButtonProps> {\n constructor(props: ButtonProps = {}) {\n super(props)\n if (props.onClick != null && typeof props.onClick !== 'function') {\n throw new TypeError('Button onClick must be a function')\n }\n }\n\n render(): FrayChild {\n const {\n children = [],\n label,\n type = 'button',\n disabled = false,\n pressed,\n busy = false,\n busyLabel,\n id,\n name,\n value,\n title,\n ariaLabel,\n onClick,\n } = this.props\n const hasChildren = Array.isArray(children)\n ? children.length > 0\n : children != null && typeof children !== 'boolean'\n const normalContent = hasChildren ? children : (label ?? '')\n const content = busy ? (busyLabel ?? normalContent) : normalContent\n const unavailable = disabled || busy\n\n return <button\n id={id}\n name={name}\n value={value == null ? undefined : String(value)}\n title={title}\n type={type}\n disabled={unavailable}\n className={componentClass(this.props) || undefined}\n data-fray-component=\"button\"\n aria-label={ariaLabel}\n aria-pressed={pressed == null ? null : String(Boolean(pressed))}\n aria-busy={busy ? 'true' : null}\n onClick={(event: MouseEvent) => {\n if (!unavailable) invoke(onClick, event)\n }}\n >{content}</button>\n }\n\n static baseStyles = [\n ['button[data-fray-component=\"button\"]', ['uiline', 'button']],\n ]\n\n static css = css`\n button[data-fray-component=\"button\"] {\n font-family: inherit;\n }\n `\n}\n"],"names":["nextControlId","controlId","prefix","provided","createValueEmitter","component","props","fallback","purpose","assertEmitter","initialValue","options","Emitter","value","name","componentClass","invoke","callback","args","assertOptions","describeState","FilterMode","Checkbox","Component","__publicField","componentType","validateSymbols","emitterProps","direction","event","currentIndex","state","nextIndex","nextValue","label","disabled","required","semanticState","symbol","stateName","checked","Host","jsx","jsxs","css","symbols","tuple","Button","children","type","pressed","busy","busyLabel","id","title","ariaLabel","onClick","normalContent","content","unavailable"],"mappings":"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"}