@frontpanel/vue 0.1.0 → 0.3.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.
package/README.md CHANGED
@@ -72,7 +72,7 @@ const playing = ref(false)
72
72
  | `FpLcd`, `FpLcdLine` | LCD glass, and a line of text on it with optional unlit segments (`ghost`, `cells`) and a left-to-right `redraw` |
73
73
  | `FpLed` | A `green`, `amber` or `red` LED; `lit`, and `blink` to confirm an action |
74
74
  | `FpHousing`, `FpWell`, `FpSilk`, `FpScrew` | A dark housing for LEDs, a recessed well, a silkscreened label, a screw head |
75
- | `FpIcon` | An 18-glyph 16 px pixel icon set (`fpIconNames`) |
75
+ | `FpIcon` | A 19-glyph 16 px pixel icon set (`fpIconNames`) |
76
76
 
77
77
  Element components take Reka's `as` and `asChild`.
78
78
 
@@ -0,0 +1,31 @@
1
+ export interface FpKnobProps {
2
+ /** The lowest value, at the knob's 7 o'clock stop. */
3
+ min?: number;
4
+ /** The highest value, at its 5 o'clock stop. */
5
+ max?: number;
6
+ /** The step values snap to. PageUp and PageDown move ten steps. */
7
+ step?: number;
8
+ /** A silkscreen label under the knob, which also names it. Without one, give it an `aria-label`. */
9
+ label?: string;
10
+ /** Turns the value into the words a screen reader says, such as `v => `${v} dB``. */
11
+ valueText?: (value: number) => string;
12
+ disabled?: boolean;
13
+ }
14
+ type __VLS_Props = FpKnobProps;
15
+ type __VLS_ModelProps = {
16
+ modelValue?: number;
17
+ };
18
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
19
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
+ valueCommit: (value: number) => any;
21
+ "update:modelValue": (value: number) => any;
22
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
23
+ onValueCommit?: ((value: number) => any) | undefined;
24
+ "onUpdate:modelValue"?: ((value: number) => any) | undefined;
25
+ }>, {
26
+ min: number;
27
+ max: number;
28
+ step: number;
29
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const _default: typeof __VLS_export;
31
+ export default _default;
@@ -1,3 +1,4 @@
1
+ import type { FpLens } from './lens';
1
2
  export type FpLedColor = 'green' | 'amber' | 'red';
2
3
  export interface FpLedProps {
3
4
  /** The colour it lights in. */
@@ -6,6 +7,8 @@ export interface FpLedProps {
6
7
  lit?: boolean;
7
8
  /** Blinks twice when it lights, then holds, to confirm an action. Re-key the LED to blink again. */
8
9
  blink?: boolean;
10
+ /** How its light spreads. Unset, it takes the lens set around it (`fp-lens-*`), else diffused. */
11
+ lens?: FpLens;
9
12
  /** Announces the LED as an image with this name. Without it the LED is decorative: say its state in text nearby. */
10
13
  label?: string;
11
14
  }
@@ -0,0 +1,32 @@
1
+ import type { FpLens } from './lens';
2
+ export interface FpMeterProps {
3
+ /** The level to show. Values past the ends light all or none of it. */
4
+ value?: number;
5
+ /** The level at the bottom (or the start, lying on its side). */
6
+ min?: number;
7
+ /** The level at the top (or the end). */
8
+ max?: number;
9
+ /** How many LED segments it has. A segment lights once the value reaches it. */
10
+ segments?: number;
11
+ /** Where amber begins, in the value's units. Defaults to 70 percent of the range. */
12
+ amberAt?: number;
13
+ /** Where red begins, in the value's units. Defaults to 90 percent of the range. */
14
+ redAt?: number;
15
+ /** Stands up, like a channel's level, or lies on its side. */
16
+ orientation?: 'vertical' | 'horizontal';
17
+ /** How its segments light. Unset, it takes the lens set around it (`fp-lens-*`), else diffused. */
18
+ lens?: FpLens;
19
+ /** A silkscreen label under the meter, which also names it. Without one, give it an `aria-label`. */
20
+ label?: string;
21
+ /** Turns the value into the words a screen reader says, such as `v => `${v} dB``. */
22
+ valueText?: (value: number) => string;
23
+ }
24
+ declare const __VLS_export: import("vue").DefineComponent<FpMeterProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FpMeterProps> & Readonly<{}>, {
25
+ value: number;
26
+ min: number;
27
+ max: number;
28
+ segments: number;
29
+ orientation: "vertical" | "horizontal";
30
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import type { FpLedColor } from './FpLed.vue';
2
+ import type { FpLens } from './lens';
3
+ export interface FpReadoutProps {
4
+ /**
5
+ * What it shows. Digits, a minus, a space and the letters a seven-segment display can draw; a `.`
6
+ * lights the decimal point of the digit before it, and a `:` adds a colon.
7
+ */
8
+ value: string | number;
9
+ /** How many digit cells it has, padded with dark cells on the left. Colons do not count. */
10
+ digits?: number;
11
+ /** The colour its segments light in. */
12
+ color?: FpLedColor;
13
+ /** How its segments light. Unset, it takes the lens set around it (`fp-lens-*`), else diffused. */
14
+ lens?: FpLens;
15
+ /** Turns the value into the words a screen reader says, such as `v => `${v} dB``. */
16
+ valueText?: (value: string) => string;
17
+ }
18
+ declare const __VLS_export: import("vue").DefineComponent<FpReadoutProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FpReadoutProps> & Readonly<{}>, {
19
+ color: FpLedColor;
20
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -0,0 +1,34 @@
1
+ export interface FpSliderProps {
2
+ /** The lowest value, at the bottom (or the start, lying on its side). */
3
+ min?: number;
4
+ /** The highest value, at the top (or the end). */
5
+ max?: number;
6
+ /** The step values snap to. PageUp, PageDown and Shift with an arrow move ten steps. */
7
+ step?: number;
8
+ /** Stands up, like a mixer channel, or lies on its side. */
9
+ orientation?: 'vertical' | 'horizontal';
10
+ /** A silkscreen label under the fader, which also names it. Without one, give it an `aria-label`. */
11
+ label?: string;
12
+ /** Turns the value into the words a screen reader says, such as `v => `${v} dB``. */
13
+ valueText?: (value: number) => string;
14
+ disabled?: boolean;
15
+ }
16
+ type __VLS_Props = FpSliderProps;
17
+ type __VLS_ModelProps = {
18
+ modelValue?: number;
19
+ };
20
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
21
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
22
+ valueCommit: (value: number) => any;
23
+ "update:modelValue": (value: number) => any;
24
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
25
+ onValueCommit?: ((value: number) => any) | undefined;
26
+ "onUpdate:modelValue"?: ((value: number) => any) | undefined;
27
+ }>, {
28
+ min: number;
29
+ max: number;
30
+ step: number;
31
+ orientation: "vertical" | "horizontal";
32
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ declare const _default: typeof __VLS_export;
34
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import type { FpLedColor } from './FpLed.vue';
2
+ export interface FpSwitchProps {
3
+ /** A silkscreen label, which also names the switch. Without one, give it an `aria-label`. */
4
+ label?: string;
5
+ /** Where the label sits: under the switch, or level with it and before it in the line. */
6
+ labelPlacement?: 'below' | 'start';
7
+ /** Standing up, I at the top; or on its side, I on the right. */
8
+ orientation?: 'vertical' | 'horizontal';
9
+ /** The colour its lamp lights in. */
10
+ color?: FpLedColor;
11
+ disabled?: boolean;
12
+ }
13
+ type __VLS_Props = FpSwitchProps;
14
+ type __VLS_ModelProps = {
15
+ modelValue?: boolean;
16
+ };
17
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
18
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (value: boolean) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
21
+ "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
22
+ }>, {
23
+ color: FpLedColor;
24
+ orientation: "vertical" | "horizontal";
25
+ labelPlacement: "start" | "below";
26
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
+ declare const _default: typeof __VLS_export;
28
+ export default _default;
@@ -1,4 +1,10 @@
1
+ import type { PrimitiveProps } from 'reka-ui';
1
2
  export interface FpWindowProps {
3
+ /**
4
+ * The window's element. A `section` or `aside` is a landmark named by the title; a `div` is not a
5
+ * landmark.
6
+ */
7
+ as?: PrimitiveProps['as'];
2
8
  /** The window's name, shown in the title bar; it also names the window for assistive tech. */
3
9
  title: string;
4
10
  /** The title's heading level. */
@@ -15,6 +21,8 @@ export interface FpWindowProps {
15
21
  * Position the sheet and choose when to use it yourself; wrap it in `<Transition name="fp-sheet">`.
16
22
  */
17
23
  sheet?: boolean;
24
+ /** Leaves the body unpadded, for contents that run edge to edge, like a list or a rack of rows. */
25
+ flush?: boolean;
18
26
  }
19
27
  type __VLS_Slots = {
20
28
  default?: () => unknown;
@@ -26,6 +34,7 @@ declare const __VLS_base: import("vue").DefineComponent<FpWindowProps, {}, {}, {
26
34
  }, string, import("vue").PublicProps, Readonly<FpWindowProps> & Readonly<{
27
35
  onClose?: (() => any) | undefined;
28
36
  }>, {
37
+ as: import("reka-ui").AsTag | import("vue").Component;
29
38
  level: 2 | 3 | 4 | 5 | 6;
30
39
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
40
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
package/dist/icons.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type FpIconName = 'add' | 'saved' | 'settings' | 'help' | 'home' | 'undo' | 'redo' | 'save' | 'copy' | 'trash' | 'close' | 'grip' | 'left' | 'right' | 'quick' | 'grid' | 'go' | 'menu';
1
+ export type FpIconName = 'add' | 'saved' | 'settings' | 'help' | 'home' | 'undo' | 'redo' | 'save' | 'copy' | 'trash' | 'close' | 'grip' | 'left' | 'right' | 'quick' | 'grid' | 'go' | 'play' | 'menu';
2
2
  /** One path per glyph: every horizontal run of lit pixels becomes a 1 px tall rectangle. */
3
3
  export declare function toPath(rows: readonly string[]): string;
4
4
  /** Every icon name, in the order the set lists them. */
package/dist/index.d.ts CHANGED
@@ -11,18 +11,30 @@ export { default as FpHousing } from './FpHousing.vue';
11
11
  export type { FpHousingProps } from './FpHousing.vue';
12
12
  export { default as FpIcon } from './FpIcon.vue';
13
13
  export type { FpIconProps } from './FpIcon.vue';
14
+ export { default as FpKnob } from './FpKnob.vue';
15
+ export type { FpKnobProps } from './FpKnob.vue';
14
16
  export { default as FpLcd } from './FpLcd.vue';
15
17
  export type { FpLcdProps } from './FpLcd.vue';
16
18
  export { default as FpLcdLine } from './FpLcdLine.vue';
17
19
  export type { FpLcdLineProps } from './FpLcdLine.vue';
18
20
  export { default as FpLed } from './FpLed.vue';
19
21
  export type { FpLedColor, FpLedProps } from './FpLed.vue';
22
+ export { default as FpMeter } from './FpMeter.vue';
23
+ export type { FpMeterProps } from './FpMeter.vue';
24
+ export { default as FpReadout } from './FpReadout.vue';
25
+ export type { FpReadoutProps } from './FpReadout.vue';
20
26
  export { default as FpScrew } from './FpScrew.vue';
21
27
  export { default as FpSilk } from './FpSilk.vue';
22
28
  export type { FpSilkProps } from './FpSilk.vue';
29
+ export { default as FpSlider } from './FpSlider.vue';
30
+ export type { FpSliderProps } from './FpSlider.vue';
31
+ export { default as FpSwitch } from './FpSwitch.vue';
32
+ export type { FpSwitchProps } from './FpSwitch.vue';
23
33
  export { default as FpWell } from './FpWell.vue';
24
34
  export type { FpWellProps } from './FpWell.vue';
25
35
  export { default as FpWindow } from './FpWindow.vue';
26
36
  export type { FpWindowProps } from './FpWindow.vue';
27
37
  export { fpIconNames } from './icons';
28
38
  export type { FpIconName } from './icons';
39
+ export type { FpLens } from './lens';
40
+ export { fpReadoutGlyph } from './readout';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { computed as e, createBlock as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, createTextVNode as a, createVNode as o, defineComponent as s, normalizeClass as c, normalizeStyle as l, openBlock as u, renderSlot as d, resolveDynamicComponent as f, shallowRef as p, toDisplayString as m, unref as h, useId as g, useTemplateRef as _, warn as v, watch as y, withCtx as b } from "vue";
2
- import { Primitive as x } from "reka-ui";
1
+ import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, defineComponent as c, mergeModels as l, mergeProps as u, normalizeClass as d, normalizeStyle as f, openBlock as p, renderList as m, renderSlot as h, resolveDynamicComponent as g, shallowRef as _, toDisplayString as v, unref as y, useAttrs as b, useId as x, useModel as S, useTemplateRef as C, warn as w, watch as T, withCtx as E } from "vue";
2
+ import { Primitive as D, SliderRoot as O, SliderThumb as k, SliderTrack as A, SwitchRoot as ee, SwitchThumb as te } from "reka-ui";
3
3
  //#endregion
4
4
  //#region src/FpButton.vue
5
- var S = /* @__PURE__ */ s({
5
+ var j = /* @__PURE__ */ c({
6
6
  __name: "FpButton",
7
7
  props: {
8
8
  pressed: {
@@ -13,15 +13,15 @@ var S = /* @__PURE__ */ s({
13
13
  as: { default: "button" }
14
14
  },
15
15
  setup(e) {
16
- let n = e;
17
- return (e, r) => (u(), t(h(x), {
18
- as: n.as,
19
- "as-child": n.asChild,
16
+ let t = e;
17
+ return (e, r) => (p(), n(y(D), {
18
+ as: t.as,
19
+ "as-child": t.asChild,
20
20
  class: "fp-chrome-btn",
21
- type: n.as === "button" && !n.asChild ? "button" : void 0,
22
- "aria-pressed": n.pressed
21
+ type: t.as === "button" && !t.asChild ? "button" : void 0,
22
+ "aria-pressed": t.pressed
23
23
  }, {
24
- default: b(() => [d(e.$slots, "default")]),
24
+ default: E(() => [h(e.$slots, "default")]),
25
25
  _: 3
26
26
  }, 8, [
27
27
  "as",
@@ -30,7 +30,7 @@ var S = /* @__PURE__ */ s({
30
30
  "aria-pressed"
31
31
  ]));
32
32
  }
33
- }), C = /* @__PURE__ */ s({
33
+ }), ne = /* @__PURE__ */ c({
34
34
  __name: "FpCap",
35
35
  props: {
36
36
  color: { default: "white" },
@@ -42,21 +42,21 @@ var S = /* @__PURE__ */ s({
42
42
  as: { default: "button" }
43
43
  },
44
44
  setup(e) {
45
- let n = e, r = {
45
+ let t = e, r = {
46
46
  white: void 0,
47
47
  blue: "fp-cap-blue",
48
48
  amber: "fp-cap-amber",
49
49
  graphite: "fp-cap-graphite",
50
50
  berry: "fp-cap-berry"
51
51
  };
52
- return (e, i) => (u(), t(h(x), {
53
- as: n.as,
54
- "as-child": n.asChild,
55
- class: c(["fp-cap", r[n.color]]),
56
- type: n.as === "button" && !n.asChild ? "button" : void 0,
57
- "aria-pressed": n.pressed
52
+ return (e, i) => (p(), n(y(D), {
53
+ as: t.as,
54
+ "as-child": t.asChild,
55
+ class: d(["fp-cap", r[t.color]]),
56
+ type: t.as === "button" && !t.asChild ? "button" : void 0,
57
+ "aria-pressed": t.pressed
58
58
  }, {
59
- default: b(() => [d(e.$slots, "default")]),
59
+ default: E(() => [h(e.$slots, "default")]),
60
60
  _: 3
61
61
  }, 8, [
62
62
  "as",
@@ -69,7 +69,7 @@ var S = /* @__PURE__ */ s({
69
69
  });
70
70
  //#endregion
71
71
  //#region src/fit.ts
72
- function w(e, t, n, r) {
72
+ function re(e, t, n, r) {
73
73
  if (t.width <= 0 || n.width <= 0) return null;
74
74
  let i = t.width / n.width;
75
75
  if (e === "contain") {
@@ -80,7 +80,7 @@ function w(e, t, n, r) {
80
80
  }
81
81
  //#endregion
82
82
  //#region src/FpDevice.vue?vue&type=script&setup=true&lang.ts
83
- var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
83
+ var M = { class: "fp-device-body" }, N = /* @__PURE__ */ c({
84
84
  __name: "FpDevice",
85
85
  props: {
86
86
  backdrop: {
@@ -96,85 +96,85 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
96
96
  height: {},
97
97
  maxScale: { default: 1 }
98
98
  },
99
- setup(t) {
100
- let n = t, a = _("stage"), o = _("device"), s = p({
99
+ setup(e) {
100
+ let n = e, r = C("stage"), o = C("device"), s = _({
101
101
  width: 0,
102
102
  height: 0
103
- }), f = p(0), m = e(() => n.fit === "none" ? !1 : n.width !== void 0 || (v(`FpDevice: fit="${n.fit}" needs a design width; the device is not scaled.`), !1)), h = e(() => n.height ?? f.value), g = e(() => !m.value || n.fit === "none" ? null : w(n.fit, s.value, {
103
+ }), c = _(0), l = t(() => n.fit === "none" ? !1 : n.width !== void 0 || (w(`FpDevice: fit="${n.fit}" needs a design width; the device is not scaled.`), !1)), u = t(() => n.height ?? c.value), m = t(() => !l.value || n.fit === "none" ? null : re(n.fit, s.value, {
104
104
  width: n.width,
105
- height: h.value
105
+ height: u.value
106
106
  }, n.maxScale));
107
- function b() {
108
- if (!a.value || !o.value) return;
109
- let e = getComputedStyle(a.value), t = (e) => Number.parseFloat(e) || 0;
107
+ function g() {
108
+ if (!r.value || !o.value) return;
109
+ let e = getComputedStyle(r.value), t = (e) => Number.parseFloat(e) || 0;
110
110
  s.value = {
111
- width: a.value.clientWidth - t(e.paddingLeft) - t(e.paddingRight),
112
- height: a.value.clientHeight - t(e.paddingTop) - t(e.paddingBottom)
113
- }, f.value = o.value.offsetHeight;
111
+ width: r.value.clientWidth - t(e.paddingLeft) - t(e.paddingRight),
112
+ height: r.value.clientHeight - t(e.paddingTop) - t(e.paddingBottom)
113
+ }, c.value = o.value.offsetHeight;
114
114
  }
115
- y([
116
- m,
117
- a,
115
+ T([
116
+ l,
117
+ r,
118
118
  o
119
119
  ], ([e, t, n], r, i) => {
120
120
  if (!e || !t || !n || typeof ResizeObserver > "u") return;
121
- let a = new ResizeObserver(b);
121
+ let a = new ResizeObserver(g);
122
122
  a.observe(t), a.observe(n), i(() => a.disconnect());
123
123
  }, {
124
124
  flush: "post",
125
125
  immediate: !0
126
126
  });
127
- let x = e(() => m.value ? { contain: "inline-size" } : void 0), S = e(() => {
128
- if (!m.value) return { display: "contents" };
129
- if (g.value !== null) return {
130
- width: `${n.width * g.value}px`,
131
- height: `${h.value * g.value}px`,
127
+ let v = t(() => l.value ? { contain: "inline-size" } : void 0), y = t(() => {
128
+ if (!l.value) return { display: "contents" };
129
+ if (m.value !== null) return {
130
+ width: `${n.width * m.value}px`,
131
+ height: `${u.value * m.value}px`,
132
132
  marginInline: "auto"
133
133
  };
134
- }), C = e(() => {
135
- if (m.value) return {
134
+ }), b = t(() => {
135
+ if (l.value) return {
136
136
  boxSizing: "border-box",
137
137
  width: `${n.width}px`,
138
138
  height: n.height === void 0 ? void 0 : `${n.height}px`,
139
- scale: g.value ?? void 0,
139
+ scale: m.value ?? void 0,
140
140
  transformOrigin: "0 0",
141
- visibility: g.value === null ? "hidden" : void 0
141
+ visibility: m.value === null ? "hidden" : void 0
142
142
  };
143
143
  });
144
- return (e, t) => (u(), r("div", {
144
+ return (e, t) => (p(), i("div", {
145
145
  ref_key: "stage",
146
- ref: a,
147
- class: c({ "fp-device-backdrop": n.backdrop }),
148
- style: l(x.value)
149
- }, [i("div", { style: l(S.value) }, [n.rim ? (u(), r("div", {
146
+ ref: r,
147
+ class: d({ "fp-device-backdrop": n.backdrop }),
148
+ style: f(v.value)
149
+ }, [a("div", { style: f(y.value) }, [n.rim ? (p(), i("div", {
150
150
  key: 0,
151
151
  ref_key: "device",
152
152
  ref: o,
153
153
  class: "fp-device-rim",
154
- style: l(C.value)
155
- }, [i("div", T, [d(e.$slots, "default")])], 4)) : (u(), r("div", {
154
+ style: f(b.value)
155
+ }, [a("div", M, [h(e.$slots, "default")])], 4)) : (p(), i("div", {
156
156
  key: 1,
157
157
  ref_key: "device",
158
158
  ref: o,
159
159
  class: "fp-device-body",
160
- style: l(C.value)
161
- }, [d(e.$slots, "default")], 4))], 4)], 6));
160
+ style: f(b.value)
161
+ }, [h(e.$slots, "default")], 4))], 4)], 6));
162
162
  }
163
- }), D = /* @__PURE__ */ s({
163
+ }), P = /* @__PURE__ */ c({
164
164
  __name: "FpGelButton",
165
165
  props: {
166
166
  asChild: { type: Boolean },
167
167
  as: { default: "button" }
168
168
  },
169
169
  setup(e) {
170
- let n = e;
171
- return (e, r) => (u(), t(h(x), {
172
- as: n.as,
173
- "as-child": n.asChild,
170
+ let t = e;
171
+ return (e, r) => (p(), n(y(D), {
172
+ as: t.as,
173
+ "as-child": t.asChild,
174
174
  class: "fp-gel",
175
- type: n.as === "button" && !n.asChild ? "button" : void 0
175
+ type: t.as === "button" && !t.asChild ? "button" : void 0
176
176
  }, {
177
- default: b(() => [d(e.$slots, "default")]),
177
+ default: E(() => [h(e.$slots, "default")]),
178
178
  _: 3
179
179
  }, 8, [
180
180
  "as",
@@ -182,24 +182,24 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
182
182
  "type"
183
183
  ]));
184
184
  }
185
- }), O = /* @__PURE__ */ s({
185
+ }), ie = /* @__PURE__ */ c({
186
186
  __name: "FpHousing",
187
187
  props: {
188
188
  asChild: { type: Boolean },
189
189
  as: { default: "span" }
190
190
  },
191
191
  setup(e) {
192
- let n = e;
193
- return (e, r) => (u(), t(h(x), {
194
- as: n.as,
195
- "as-child": n.asChild,
192
+ let t = e;
193
+ return (e, r) => (p(), n(y(D), {
194
+ as: t.as,
195
+ "as-child": t.asChild,
196
196
  class: "fp-housing"
197
197
  }, {
198
- default: b(() => [d(e.$slots, "default")]),
198
+ default: E(() => [h(e.$slots, "default")]),
199
199
  _: 3
200
200
  }, 8, ["as", "as-child"]));
201
201
  }
202
- }), k = [
202
+ }), F = [
203
203
  "................",
204
204
  "................",
205
205
  ".....#..........",
@@ -216,7 +216,7 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
216
216
  "................",
217
217
  "................",
218
218
  "................"
219
- ], A = [
219
+ ], I = [
220
220
  "................",
221
221
  "................",
222
222
  ".........##.....",
@@ -233,7 +233,7 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
233
233
  ".........##.....",
234
234
  "................",
235
235
  "................"
236
- ], j = (e) => e.map((e) => [...e].reverse().join("")), M = {
236
+ ], L = (e) => e.map((e) => [...e].reverse().join("")), R = {
237
237
  add: [
238
238
  "................",
239
239
  "................",
@@ -270,8 +270,8 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
270
270
  "................",
271
271
  "................"
272
272
  ],
273
- left: A,
274
- right: j(A),
273
+ left: I,
274
+ right: L(I),
275
275
  go: [
276
276
  "................",
277
277
  "................",
@@ -290,8 +290,26 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
290
290
  "................",
291
291
  "................"
292
292
  ],
293
- undo: k,
294
- redo: j(k),
293
+ play: [
294
+ "................",
295
+ "................",
296
+ "....#...........",
297
+ "....###.........",
298
+ "....####........",
299
+ "....######......",
300
+ "....#######.....",
301
+ "....#########...",
302
+ "....#########...",
303
+ "....#######.....",
304
+ "....######......",
305
+ "....####........",
306
+ "....###.........",
307
+ "....#...........",
308
+ "................",
309
+ "................"
310
+ ],
311
+ undo: F,
312
+ redo: L(F),
295
313
  home: [
296
314
  "................",
297
315
  ".......##.......",
@@ -491,7 +509,7 @@ var T = { class: "fp-device-body" }, E = /* @__PURE__ */ s({
491
509
  "................"
492
510
  ]
493
511
  };
494
- function N(e) {
512
+ function z(e) {
495
513
  let t = "";
496
514
  return e.forEach((e, n) => {
497
515
  let r = 0;
@@ -507,48 +525,153 @@ function N(e) {
507
525
  }
508
526
  }), t;
509
527
  }
510
- var P = Object.keys(M), F = Object.fromEntries(P.map((e) => [e, N(M[e])])), I = [
528
+ var B = Object.keys(R), V = Object.fromEntries(B.map((e) => [e, z(R[e])])), H = [
511
529
  "role",
512
530
  "aria-label",
513
531
  "aria-hidden"
514
- ], L = ["d"], R = /* @__PURE__ */ s({
532
+ ], U = ["d"], W = /* @__PURE__ */ c({
515
533
  __name: "FpIcon",
516
534
  props: {
517
535
  name: {},
518
536
  label: {}
519
537
  },
520
- setup(t) {
521
- let n = t, a = e(() => F[n.name]);
522
- return (e, t) => (u(), r("svg", {
538
+ setup(e) {
539
+ let n = e, r = t(() => V[n.name]);
540
+ return (e, t) => (p(), i("svg", {
523
541
  viewBox: "0 0 16 16",
524
542
  class: "fp-icon",
525
543
  role: n.label ? "img" : void 0,
526
544
  "aria-label": n.label || void 0,
527
545
  "aria-hidden": n.label ? void 0 : "true"
528
- }, [i("path", { d: a.value }, null, 8, L)], 8, I));
546
+ }, [a("path", { d: r.value }, null, 8, U)], 8, H));
547
+ }
548
+ }), G = [
549
+ "tabindex",
550
+ "aria-valuemin",
551
+ "aria-valuemax",
552
+ "aria-valuenow",
553
+ "aria-valuetext",
554
+ "aria-labelledby",
555
+ "aria-disabled"
556
+ ], K = ["id"], q = 200, J = .1, Y = 270, ae = /* @__PURE__ */ c({
557
+ inheritAttrs: !1,
558
+ __name: "FpKnob",
559
+ props: /*@__PURE__*/ l({
560
+ min: { default: 0 },
561
+ max: { default: 100 },
562
+ step: { default: 1 },
563
+ label: {},
564
+ valueText: {},
565
+ disabled: { type: Boolean }
566
+ }, {
567
+ modelValue: { default: 0 },
568
+ modelModifiers: {}
569
+ }),
570
+ emits: /*@__PURE__*/ l(["valueCommit"], ["update:modelValue"]),
571
+ setup(e, { emit: n }) {
572
+ let o = e, s = n, c = S(e, "modelValue"), l = b(), d = t(() => ({
573
+ class: l.class,
574
+ style: l.style
575
+ })), m = t(() => {
576
+ let { class: e, style: t, ...n } = l;
577
+ return n;
578
+ }), h = x(), g = t(() => (String(o.step).split(".")[1] ?? "").length);
579
+ function _(e) {
580
+ let t = Math.round((e - o.min) / o.step) * o.step + o.min, n = Math.min(o.max, Math.max(o.min, t));
581
+ return Number(n.toFixed(g.value));
582
+ }
583
+ let C = t(() => _(c.value)), w = t(() => {
584
+ let e = o.max - o.min, t = e > 0 ? (C.value - o.min) / e : 0;
585
+ return Math.round(t * Y - Y / 2);
586
+ });
587
+ function T(e) {
588
+ let t = _(e);
589
+ return t !== C.value && (c.value = t, !0);
590
+ }
591
+ function E(e) {
592
+ if (o.disabled) return;
593
+ let t = o.step * 10, n = {
594
+ ArrowUp: C.value + o.step,
595
+ ArrowRight: C.value + o.step,
596
+ ArrowDown: C.value - o.step,
597
+ ArrowLeft: C.value - o.step,
598
+ PageUp: C.value + t,
599
+ PageDown: C.value - t,
600
+ Home: o.min,
601
+ End: o.max
602
+ }[e.key];
603
+ n !== void 0 && (e.preventDefault(), T(n) && s("valueCommit", _(n)));
604
+ }
605
+ let D;
606
+ function O(e) {
607
+ if (o.disabled || e.button !== 0) return;
608
+ let t = e.currentTarget;
609
+ t.setPointerCapture?.(e.pointerId), t.focus({
610
+ preventScroll: !0,
611
+ focusVisible: !1
612
+ }), D = {
613
+ pointerId: e.pointerId,
614
+ y: e.clientY,
615
+ raw: C.value,
616
+ start: C.value
617
+ };
618
+ }
619
+ function k(e) {
620
+ if (!D || e.pointerId !== D.pointerId) return;
621
+ let t = (o.max - o.min) / q * (e.shiftKey ? J : 1);
622
+ D.raw = Math.min(o.max, Math.max(o.min, D.raw + (D.y - e.clientY) * t)), D.y = e.clientY, T(D.raw);
623
+ }
624
+ function A(e) {
625
+ if (!D || e.pointerId !== D.pointerId) return;
626
+ let t = _(D.raw), n = t !== D.start;
627
+ D = void 0, n && s("valueCommit", t);
628
+ }
629
+ return (e, t) => (p(), i("div", u({ class: "fp-unit" }, d.value), [a("div", u(m.value, {
630
+ class: "fp-knob",
631
+ role: "slider",
632
+ tabindex: o.disabled ? void 0 : 0,
633
+ "aria-valuemin": o.min,
634
+ "aria-valuemax": o.max,
635
+ "aria-valuenow": C.value,
636
+ "aria-valuetext": o.valueText?.(C.value),
637
+ "aria-labelledby": o.label ? y(h) : void 0,
638
+ "aria-disabled": o.disabled || void 0,
639
+ onKeydown: E,
640
+ onPointerdown: O,
641
+ onPointermove: k,
642
+ onPointerup: A,
643
+ onPointercancel: A
644
+ }), [a("span", {
645
+ class: "fp-knob-mark",
646
+ style: f({ rotate: `${w.value}deg` })
647
+ }, null, 4)], 16, G), o.label ? (p(), i("span", {
648
+ key: 0,
649
+ id: y(h),
650
+ class: "fp-silk"
651
+ }, v(o.label), 9, K)) : r("", !0)], 16));
529
652
  }
530
- }), z = /* @__PURE__ */ s({
653
+ }), oe = /* @__PURE__ */ c({
531
654
  __name: "FpLcd",
532
655
  props: {
533
656
  asChild: { type: Boolean },
534
657
  as: { default: "div" }
535
658
  },
536
659
  setup(e) {
537
- let n = e;
538
- return (e, r) => (u(), t(h(x), {
539
- as: n.as,
540
- "as-child": n.asChild,
660
+ let t = e;
661
+ return (e, r) => (p(), n(y(D), {
662
+ as: t.as,
663
+ "as-child": t.asChild,
541
664
  class: "fp-lcd"
542
665
  }, {
543
- default: b(() => [d(e.$slots, "default")]),
666
+ default: E(() => [h(e.$slots, "default")]),
544
667
  _: 3
545
668
  }, 8, ["as", "as-child"]));
546
669
  }
547
- }), B = {
670
+ }), se = {
548
671
  key: 0,
549
672
  class: "fp-lcd-ghost",
550
673
  "aria-hidden": "true"
551
- }, V = { key: 2 }, H = /* @__PURE__ */ s({
674
+ }, ce = { key: 2 }, le = /* @__PURE__ */ c({
552
675
  __name: "FpLcdLine",
553
676
  props: {
554
677
  text: {},
@@ -558,30 +681,35 @@ var P = Object.keys(M), F = Object.fromEntries(P.map((e) => [e, N(M[e])])), I =
558
681
  asChild: { type: Boolean },
559
682
  as: { default: "p" }
560
683
  },
561
- setup(i) {
562
- let a = i, o = e(() => "8".repeat(a.cells ?? a.text.length));
563
- return (e, i) => (u(), t(h(x), {
684
+ setup(e) {
685
+ let a = e, o = t(() => "8".repeat(a.cells ?? a.text.length));
686
+ return (e, t) => (p(), n(y(D), {
564
687
  as: a.as,
565
688
  "as-child": a.asChild,
566
689
  class: "fp-lcd-line"
567
690
  }, {
568
- default: b(() => [a.ghost ? (u(), r("span", B, m(o.value), 1)) : n("", !0), a.redraw ? (u(), r("span", {
691
+ default: E(() => [a.ghost ? (p(), i("span", se, v(o.value), 1)) : r("", !0), a.redraw ? (p(), i("span", {
569
692
  key: a.text,
570
693
  class: "fp-lcd-redraw"
571
- }, m(a.text), 1)) : (u(), r("span", V, m(a.text), 1))]),
694
+ }, v(a.text), 1)) : (p(), i("span", ce, v(a.text), 1))]),
572
695
  _: 1
573
696
  }, 8, ["as", "as-child"]));
574
697
  }
575
- }), U = [
698
+ }), X = {
699
+ flat: "fp-lens-flat",
700
+ diffused: "fp-lens-diffused",
701
+ clear: "fp-lens-clear"
702
+ }, ue = [
576
703
  "role",
577
704
  "aria-label",
578
705
  "aria-hidden"
579
- ], W = /* @__PURE__ */ s({
706
+ ], de = /* @__PURE__ */ c({
580
707
  __name: "FpLed",
581
708
  props: {
582
709
  color: { default: "green" },
583
710
  lit: { type: Boolean },
584
711
  blink: { type: Boolean },
712
+ lens: {},
585
713
  label: {}
586
714
  },
587
715
  setup(e) {
@@ -590,92 +718,393 @@ var P = Object.keys(M), F = Object.fromEntries(P.map((e) => [e, N(M[e])])), I =
590
718
  amber: "fp-led-amber",
591
719
  red: "fp-led-red"
592
720
  };
593
- return (e, i) => (u(), r("span", {
594
- class: c(["fp-led", [n[t.color], {
595
- "fp-led-lit": t.lit,
596
- "fp-blink-twice": t.lit && t.blink
597
- }]]),
721
+ return (e, r) => (p(), i("span", {
722
+ class: d(["fp-led", [
723
+ n[t.color],
724
+ t.lens && y(X)[t.lens],
725
+ {
726
+ "fp-led-lit": t.lit,
727
+ "fp-blink-twice": t.lit && t.blink
728
+ }
729
+ ]]),
598
730
  role: t.label ? "img" : void 0,
599
731
  "aria-label": t.label || void 0,
600
732
  "aria-hidden": t.label ? void 0 : "true"
601
- }, null, 10, U));
733
+ }, null, 10, ue));
734
+ }
735
+ }), fe = [
736
+ "data-orientation",
737
+ "aria-valuemin",
738
+ "aria-valuemax",
739
+ "aria-valuenow",
740
+ "aria-valuetext",
741
+ "aria-labelledby"
742
+ ], pe = ["id"], me = /* @__PURE__ */ c({
743
+ inheritAttrs: !1,
744
+ __name: "FpMeter",
745
+ props: {
746
+ value: { default: 0 },
747
+ min: { default: 0 },
748
+ max: { default: 100 },
749
+ segments: { default: 12 },
750
+ amberAt: {},
751
+ redAt: {},
752
+ orientation: { default: "vertical" },
753
+ lens: {},
754
+ label: {},
755
+ valueText: {}
756
+ },
757
+ setup(e) {
758
+ let n = e, o = b(), s = t(() => ({
759
+ class: o.class,
760
+ style: o.style
761
+ })), c = t(() => {
762
+ let { class: e, style: t, ...n } = o;
763
+ return n;
764
+ }), l = x(), d = t(() => Math.min(n.max, Math.max(n.min, n.value)));
765
+ function f(e) {
766
+ let t = n.max - n.min;
767
+ return t > 0 ? Math.min(1, Math.max(0, (e - n.min) / t)) : 0;
768
+ }
769
+ function m(e, t) {
770
+ return t(f(e) * n.segments + 1e-9) / n.segments;
771
+ }
772
+ let h = t(() => {
773
+ let e = n.max - n.min;
774
+ return {
775
+ "--fp-meter-level": String(m(d.value, Math.floor)),
776
+ "--fp-meter-segments": String(n.segments),
777
+ "--fp-meter-amber": String(m(n.amberAt ?? n.min + e * .7, Math.round)),
778
+ "--fp-meter-red": String(m(n.redAt ?? n.min + e * .9, Math.round))
779
+ };
780
+ });
781
+ return (e, t) => (p(), i("div", u({ class: "fp-unit" }, s.value), [a("div", u(c.value, {
782
+ class: ["fp-meter", n.lens && y(X)[n.lens]],
783
+ role: "meter",
784
+ "data-orientation": n.orientation,
785
+ "aria-valuemin": n.min,
786
+ "aria-valuemax": n.max,
787
+ "aria-valuenow": d.value,
788
+ "aria-valuetext": n.valueText?.(d.value),
789
+ "aria-labelledby": n.label ? y(l) : void 0,
790
+ style: h.value
791
+ }), null, 16, fe), n.label ? (p(), i("span", {
792
+ key: 0,
793
+ id: y(l),
794
+ class: "fp-silk"
795
+ }, v(n.label), 9, pe)) : r("", !0)], 16));
796
+ }
797
+ }), Z = {
798
+ 0: "abcdef",
799
+ 1: "bc",
800
+ 2: "abdeg",
801
+ 3: "abcdg",
802
+ 4: "bcfg",
803
+ 5: "acdfg",
804
+ 6: "acdefg",
805
+ 7: "abc",
806
+ 8: "abcdefg",
807
+ 9: "abcdfg",
808
+ "-": "g",
809
+ _: "d",
810
+ "°": "abfg",
811
+ " ": "",
812
+ A: "abcefg",
813
+ B: "cdefg",
814
+ C: "adef",
815
+ c: "deg",
816
+ D: "bcdeg",
817
+ E: "adefg",
818
+ F: "aefg",
819
+ G: "acdef",
820
+ H: "bcefg",
821
+ h: "cefg",
822
+ I: "ef",
823
+ J: "bcde",
824
+ L: "def",
825
+ N: "ceg",
826
+ O: "abcdef",
827
+ o: "cdeg",
828
+ P: "abefg",
829
+ R: "eg",
830
+ S: "acdfg",
831
+ T: "defg",
832
+ U: "bcdef",
833
+ u: "cde",
834
+ Y: "bcdfg"
835
+ };
836
+ function Q(e) {
837
+ return Z[e] ?? Z[e.toUpperCase()] ?? "";
838
+ }
839
+ //#endregion
840
+ //#region src/FpReadout.vue?vue&type=script&setup=true&lang.ts
841
+ var he = { class: "fp-readout-text" }, ge = ["data-colon"], _e = { class: "fp-readout-lit" }, ve = ["data-segment"], ye = {
842
+ key: 0,
843
+ "data-segment": "dp"
844
+ }, be = /* @__PURE__ */ c({
845
+ __name: "FpReadout",
846
+ props: {
847
+ value: {},
848
+ digits: {},
849
+ color: { default: "green" },
850
+ lens: {},
851
+ valueText: {}
852
+ },
853
+ setup(n) {
854
+ let o = n, s = {
855
+ green: "fp-led-green",
856
+ amber: "fp-led-amber",
857
+ red: "fp-led-red"
858
+ }, c = t(() => String(o.value)), l = t(() => {
859
+ let e = [];
860
+ for (let t of c.value) {
861
+ let n = e.at(-1);
862
+ t === ":" ? e.push({ colon: !0 }) : t === "." && n && !n.colon && !n.dot ? n.dot = !0 : t === "." ? e.push({
863
+ colon: !1,
864
+ lit: "",
865
+ dot: !0
866
+ }) : e.push({
867
+ colon: !1,
868
+ lit: Q(t),
869
+ dot: !1
870
+ });
871
+ }
872
+ let t = e.filter((e) => !e.colon).length;
873
+ return [...Array.from({ length: Math.max(0, (o.digits ?? 0) - t) }, () => ({
874
+ colon: !1,
875
+ lit: "",
876
+ dot: !1
877
+ })), ...e];
878
+ });
879
+ return (t, n) => (p(), i("span", { class: d(["fp-readout", [s[o.color], o.lens && y(X)[o.lens]]]) }, [a("span", he, v(o.valueText ? o.valueText(c.value) : c.value), 1), (p(!0), i(e, null, m(l.value, (t, o) => (p(), i("span", {
880
+ key: o,
881
+ class: "fp-readout-cell",
882
+ "data-colon": t.colon ? "" : void 0,
883
+ "aria-hidden": "true"
884
+ }, [a("span", _e, [t.colon ? (p(), i(e, { key: 0 }, [n[0] ||= a("span", { "data-segment": "colon-upper" }, null, -1), n[1] ||= a("span", { "data-segment": "colon-lower" }, null, -1)], 64)) : (p(), i(e, { key: 1 }, [(p(!0), i(e, null, m(t.lit, (e) => (p(), i("span", {
885
+ key: e,
886
+ "data-segment": e
887
+ }, null, 8, ve))), 128)), t.dot ? (p(), i("span", ye)) : r("", !0)], 64))])], 8, ge))), 128))], 2));
602
888
  }
603
- }), G = {
889
+ }), $ = {
604
890
  class: "fp-screw",
605
891
  "aria-hidden": "true"
606
- }, K = /* @__PURE__ */ s({
892
+ }, xe = /* @__PURE__ */ c({
607
893
  __name: "FpScrew",
608
894
  setup(e) {
609
- return (e, t) => (u(), r("span", G));
895
+ return (e, t) => (p(), i("span", $));
610
896
  }
611
- }), q = /* @__PURE__ */ s({
897
+ }), Se = /* @__PURE__ */ c({
612
898
  __name: "FpSilk",
613
899
  props: {
614
900
  asChild: { type: Boolean },
615
901
  as: { default: "span" }
616
902
  },
617
903
  setup(e) {
618
- let n = e;
619
- return (e, r) => (u(), t(h(x), {
620
- as: n.as,
621
- "as-child": n.asChild,
904
+ let t = e;
905
+ return (e, r) => (p(), n(y(D), {
906
+ as: t.as,
907
+ "as-child": t.asChild,
622
908
  class: "fp-silk"
623
909
  }, {
624
- default: b(() => [d(e.$slots, "default")]),
910
+ default: E(() => [h(e.$slots, "default")]),
625
911
  _: 3
626
912
  }, 8, ["as", "as-child"]));
627
913
  }
628
- }), J = /* @__PURE__ */ s({
914
+ }), Ce = ["id"], we = /* @__PURE__ */ c({
915
+ inheritAttrs: !1,
916
+ __name: "FpSlider",
917
+ props: /*@__PURE__*/ l({
918
+ min: { default: 0 },
919
+ max: { default: 100 },
920
+ step: { default: 1 },
921
+ orientation: { default: "vertical" },
922
+ label: {},
923
+ valueText: {},
924
+ disabled: { type: Boolean }
925
+ }, {
926
+ modelValue: { default: 0 },
927
+ modelModifiers: {}
928
+ }),
929
+ emits: /*@__PURE__*/ l(["valueCommit"], ["update:modelValue"]),
930
+ setup(e, { emit: n }) {
931
+ let a = e, o = n, c = S(e, "modelValue"), l = b(), d = t(() => ({
932
+ class: l.class,
933
+ style: l.style
934
+ })), f = t(() => {
935
+ let { class: e, style: t, ...n } = l;
936
+ return n;
937
+ }), m = x(), h = t(() => [c.value]);
938
+ function g(e) {
939
+ e?.[0] !== void 0 && (c.value = e[0]);
940
+ }
941
+ let _ = C("unit");
942
+ function w(e) {
943
+ a.disabled || e.button !== 0 || _.value?.querySelector("[role=\"slider\"]")?.focus({
944
+ preventScroll: !0,
945
+ focusVisible: !1
946
+ });
947
+ }
948
+ function T(e) {
949
+ e[0] !== void 0 && o("valueCommit", e[0]);
950
+ }
951
+ return (e, t) => (p(), i("div", u({
952
+ ref_key: "unit",
953
+ ref: _,
954
+ class: "fp-unit"
955
+ }, d.value, { onPointerdownCapture: w }), [s(y(O), {
956
+ class: "fp-fader",
957
+ "model-value": h.value,
958
+ min: a.min,
959
+ max: a.max,
960
+ step: a.step,
961
+ orientation: a.orientation,
962
+ disabled: a.disabled,
963
+ "onUpdate:modelValue": g,
964
+ onValueCommit: T
965
+ }, {
966
+ default: E(() => [s(y(A), { class: "fp-fader-slot" }), s(y(k), u(f.value, {
967
+ class: "fp-fader-cap",
968
+ "aria-valuetext": a.valueText?.(c.value),
969
+ "aria-labelledby": a.label ? y(m) : void 0,
970
+ "aria-disabled": a.disabled || void 0
971
+ }), null, 16, [
972
+ "aria-valuetext",
973
+ "aria-labelledby",
974
+ "aria-disabled"
975
+ ])]),
976
+ _: 1
977
+ }, 8, [
978
+ "model-value",
979
+ "min",
980
+ "max",
981
+ "step",
982
+ "orientation",
983
+ "disabled"
984
+ ]), a.label ? (p(), i("span", {
985
+ key: 0,
986
+ id: y(m),
987
+ class: "fp-silk"
988
+ }, v(a.label), 9, Ce)) : r("", !0)], 16));
989
+ }
990
+ }), Te = ["data-label-placement"], Ee = ["id"], De = /* @__PURE__ */ c({
991
+ inheritAttrs: !1,
992
+ __name: "FpSwitch",
993
+ props: /*@__PURE__*/ l({
994
+ label: {},
995
+ labelPlacement: { default: "below" },
996
+ orientation: { default: "vertical" },
997
+ color: { default: "red" },
998
+ disabled: { type: Boolean }
999
+ }, {
1000
+ modelValue: {
1001
+ type: Boolean,
1002
+ default: !1
1003
+ },
1004
+ modelModifiers: {}
1005
+ }),
1006
+ emits: ["update:modelValue"],
1007
+ setup(e) {
1008
+ let n = e, o = {
1009
+ green: "fp-led-green",
1010
+ amber: "fp-led-amber",
1011
+ red: "fp-led-red"
1012
+ }, c = S(e, "modelValue"), l = x(), d = b(), f = t(() => ({
1013
+ class: d.class,
1014
+ style: d.style
1015
+ })), m = t(() => {
1016
+ let { class: e, style: t, ...n } = d;
1017
+ return n;
1018
+ });
1019
+ return (e, t) => (p(), i("div", u({
1020
+ class: "fp-unit",
1021
+ "data-label-placement": n.labelPlacement
1022
+ }, f.value), [s(y(ee), u(m.value, {
1023
+ modelValue: c.value,
1024
+ "onUpdate:modelValue": t[0] ||= (e) => c.value = e,
1025
+ class: ["fp-switch", o[n.color]],
1026
+ "data-orientation": n.orientation,
1027
+ disabled: n.disabled,
1028
+ "aria-labelledby": n.label ? y(l) : void 0
1029
+ }), {
1030
+ default: E(() => [s(y(te), { class: "fp-switch-rocker" }, {
1031
+ default: E(() => [...t[1] ||= [a("span", { class: "fp-switch-lamp" }, null, -1), a("span", { class: "fp-switch-face" }, null, -1)]]),
1032
+ _: 1
1033
+ })]),
1034
+ _: 1
1035
+ }, 16, [
1036
+ "modelValue",
1037
+ "class",
1038
+ "data-orientation",
1039
+ "disabled",
1040
+ "aria-labelledby"
1041
+ ]), n.label ? (p(), i("span", {
1042
+ key: 0,
1043
+ id: y(l),
1044
+ class: "fp-silk"
1045
+ }, v(n.label), 9, Ee)) : r("", !0)], 16, Te));
1046
+ }
1047
+ }), Oe = /* @__PURE__ */ c({
629
1048
  __name: "FpWell",
630
1049
  props: {
631
1050
  asChild: { type: Boolean },
632
1051
  as: { default: "div" }
633
1052
  },
634
1053
  setup(e) {
635
- let n = e;
636
- return (e, r) => (u(), t(h(x), {
637
- as: n.as,
638
- "as-child": n.asChild,
1054
+ let t = e;
1055
+ return (e, r) => (p(), n(y(D), {
1056
+ as: t.as,
1057
+ "as-child": t.asChild,
639
1058
  class: "fp-well"
640
1059
  }, {
641
- default: b(() => [d(e.$slots, "default")]),
1060
+ default: E(() => [h(e.$slots, "default")]),
642
1061
  _: 3
643
1062
  }, 8, ["as", "as-child"]));
644
1063
  }
645
- }), Y = ["aria-labelledby"], X = { class: "fp-module-title" }, Z = { class: "fp-window-body" }, Q = /* @__PURE__ */ s({
1064
+ }), ke = { class: "fp-module-title" }, Ae = /* @__PURE__ */ c({
646
1065
  __name: "FpWindow",
647
1066
  props: {
1067
+ as: { default: "section" },
648
1068
  title: {},
649
1069
  level: { default: 2 },
650
1070
  closable: { type: Boolean },
651
1071
  closeLabel: {},
652
- sheet: { type: Boolean }
1072
+ sheet: { type: Boolean },
1073
+ flush: { type: Boolean }
653
1074
  },
654
1075
  emits: ["close"],
655
- setup(e, { emit: s }) {
656
- let l = e, p = s, _ = g();
657
- return (e, s) => (u(), r("section", {
658
- class: c(["fp-window", [l.sheet ? "fp-sheet-panel" : "fp-module"]]),
659
- "aria-labelledby": h(_)
660
- }, [i("div", X, [
661
- (u(), t(f(`h${l.level}`), {
662
- id: h(_),
663
- class: "fp-silk fp-window-title"
664
- }, {
665
- default: b(() => [a(m(l.title), 1)]),
666
- _: 1
667
- }, 8, ["id"])),
668
- d(e.$slots, "actions"),
669
- l.closable ? (u(), t(S, {
670
- key: 0,
671
- "aria-label": l.closeLabel ?? `Close ${l.title}`,
672
- onClick: s[0] ||= (e) => p("close")
673
- }, {
674
- default: b(() => [o(R, { name: "close" })]),
675
- _: 1
676
- }, 8, ["aria-label"])) : n("", !0)
677
- ]), i("div", Z, [d(e.$slots, "default")])], 10, Y));
1076
+ setup(e, { emit: t }) {
1077
+ let i = e, c = t, l = x();
1078
+ return (e, t) => (p(), n(y(D), {
1079
+ as: i.as,
1080
+ class: d(["fp-window", [i.sheet ? "fp-sheet-panel" : "fp-module"]]),
1081
+ "aria-labelledby": y(l)
1082
+ }, {
1083
+ default: E(() => [a("div", ke, [
1084
+ (p(), n(g(`h${i.level}`), {
1085
+ id: y(l),
1086
+ class: "fp-silk fp-window-title"
1087
+ }, {
1088
+ default: E(() => [o(v(i.title), 1)]),
1089
+ _: 1
1090
+ }, 8, ["id"])),
1091
+ h(e.$slots, "actions"),
1092
+ i.closable ? (p(), n(j, {
1093
+ key: 0,
1094
+ "aria-label": i.closeLabel ?? `Close ${i.title}`,
1095
+ onClick: t[0] ||= (e) => c("close")
1096
+ }, {
1097
+ default: E(() => [s(W, { name: "close" })]),
1098
+ _: 1
1099
+ }, 8, ["aria-label"])) : r("", !0)
1100
+ ]), a("div", { class: d(i.flush ? void 0 : "fp-window-body") }, [h(e.$slots, "default")], 2)]),
1101
+ _: 3
1102
+ }, 8, [
1103
+ "as",
1104
+ "class",
1105
+ "aria-labelledby"
1106
+ ]));
678
1107
  }
679
1108
  });
680
1109
  //#endregion
681
- export { S as FpButton, C as FpCap, E as FpDevice, D as FpGelButton, O as FpHousing, R as FpIcon, z as FpLcd, H as FpLcdLine, W as FpLed, K as FpScrew, q as FpSilk, J as FpWell, Q as FpWindow, P as fpIconNames };
1110
+ export { j as FpButton, ne as FpCap, N as FpDevice, P as FpGelButton, ie as FpHousing, W as FpIcon, ae as FpKnob, oe as FpLcd, le as FpLcdLine, de as FpLed, me as FpMeter, be as FpReadout, xe as FpScrew, Se as FpSilk, we as FpSlider, De as FpSwitch, Oe as FpWell, Ae as FpWindow, B as fpIconNames, Q as fpReadoutGlyph };
package/dist/lens.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ /** How an LED's light spreads: an even fill, a soft hot spot over its chip, or a bright one. */
2
+ export type FpLens = 'flat' | 'diffused' | 'clear';
3
+ export declare const lensClass: Record<FpLens, string>;
@@ -0,0 +1,2 @@
1
+ /** The segments a character lights, as letters a to g; none for a character it cannot draw. */
2
+ export declare function fpReadoutGlyph(character: string): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@frontpanel/vue",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.3.0",
5
5
  "description": "Vue 3 components for the Frontpanel early-2000s hardware skin: a scale-to-fit device frame, windows, chrome and gel buttons, caps, LCDs and LEDs, built on Reka UI.",
6
6
  "author": "Dulan Katukurundage",
7
7
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "reka-ui": "^2.11.0",
39
- "@frontpanel/css": "^0.1.0"
39
+ "@frontpanel/css": "^0.3.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@tailwindcss/oxide": "^4.3.3",