@genesislcap/foundation-ui 14.416.1 → 14.417.0-FUI-0-react-renderers.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.
@@ -0,0 +1,46 @@
1
+ type Constructor<T = object> = new (...args: any[]) => T;
2
+ interface AffixMixinBase {
3
+ ariaDescribedby: string | null;
4
+ id: string;
5
+ }
6
+ /**
7
+ * Mixin that adds prefix/suffix affix support with screen-reader handling to an input field component.
8
+ * Shared between TextField and NumberField to keep the behaviour consistent and avoid duplication.
9
+ */
10
+ export declare function AffixMixin<TBase extends Constructor<AffixMixinBase>>(Base: TBase): {
11
+ new (...args: any[]): {
12
+ /**
13
+ * Optional non-editable label shown on the left inside the field, before the input.
14
+ */
15
+ prefix: string;
16
+ /**
17
+ * Optional non-editable suffix (e.g. unit label) shown on the right inside the field.
18
+ */
19
+ suffix: string;
20
+ /**
21
+ * When true, prefix/suffix are not exposed to assistive technology (`aria-hidden` on affixes,
22
+ * and their ids are omitted from the control's `aria-describedby`).
23
+ * Use only when the unit or symbol is redundant with the visible label or other text.
24
+ * @remarks
25
+ * By default, affix text is **included** for screen readers: stable ids are assigned to the
26
+ * affix nodes and referenced from the input's `aria-describedby` (merged with any author
27
+ * `aria-describedby`), which announces them as supplementary description after the field name
28
+ * from the label.
29
+ * For cases where the affix should be part of the accessible **name** instead (e.g. currency
30
+ * code read as part of the label), set `hide-affix-from-screen-reader` and wire
31
+ * `aria-labelledby` on the host to reference the label slot and your own elements, or provide
32
+ * a single `aria-label` that includes the full name.
33
+ */
34
+ hideAffixFromScreenReader: boolean;
35
+ /**
36
+ * Merges the host `aria-describedby` with ids of the prefix/suffix nodes when those affixes
37
+ * are exposed to screen readers.
38
+ * @internal
39
+ */
40
+ get controlAriaDescribedby(): string | undefined;
41
+ ariaDescribedby: string | null;
42
+ id: string;
43
+ };
44
+ } & TBase;
45
+ export {};
46
+ //# sourceMappingURL=affix-mixin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affix-mixin.d.ts","sourceRoot":"","sources":["../../../src/_common/affix-mixin.ts"],"names":[],"mappings":"AAEA,KAAK,WAAW,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAEzD,UAAU,cAAc;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,SAAS,WAAW,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK;kBAXpC,GAAG,EAAE;QAa9C;;WAEG;gBACW,MAAM;QAEpB;;WAEG;gBACW,MAAM;QAEpB;;;;;;;;;;;;;WAaG;mCAEwB,OAAO;QAElC;;;;WAIG;sCAC2B,MAAM,GAAG,SAAS;yBA1CjC,MAAM,GAAG,IAAI;YAC1B,MAAM;;UAsEX"}
@@ -0,0 +1,2 @@
1
+ export declare const sharedFieldStyles: import("@microsoft/fast-element").ElementStyles;
2
+ //# sourceMappingURL=field-styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-styles.d.ts","sourceRoot":"","sources":["../../../src/_common/field-styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,iDA4D7B,CAAC"}
@@ -1,3 +1,5 @@
1
+ export * from './affix-mixin';
1
2
  export * from './base-file-component';
3
+ export * from './field-styles';
2
4
  export * from './icons';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_common/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_common/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC"}
@@ -1,9 +1,19 @@
1
1
  import { NumberField as FASTNumberField } from '@microsoft/fast-components';
2
2
  import type { NumberFieldOptions } from '@microsoft/fast-foundation';
3
+ declare const NumberField_base: {
4
+ new (...args: any[]): {
5
+ prefix: string;
6
+ suffix: string;
7
+ hideAffixFromScreenReader: boolean;
8
+ get controlAriaDescribedby(): string | undefined;
9
+ ariaDescribedby: string | null;
10
+ id: string;
11
+ };
12
+ } & typeof FASTNumberField;
3
13
  /**
4
14
  * @tagname %%prefix%%-number-field
5
15
  */
6
- export declare class NumberField extends FASTNumberField {
16
+ export declare class NumberField extends NumberField_base {
7
17
  autocomplete: string;
8
18
  private autocompleteChanged;
9
19
  hideStep: boolean;
@@ -33,4 +43,5 @@ export declare const defaultNumberFieldConfig: {
33
43
  * HTML Element: \<foundation-number-field\>
34
44
  */
35
45
  export declare const foundationNumberField: (overrideDefinition?: import("@microsoft/fast-foundation").OverrideFoundationElementDefinition<NumberFieldOptions>) => import("@microsoft/fast-foundation").FoundationElementRegistry<NumberFieldOptions, import("@microsoft/fast-element").Constructable<import("@microsoft/fast-foundation").FoundationElement>>;
46
+ export {};
36
47
  //# sourceMappingURL=number-field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"number-field.d.ts","sourceRoot":"","sources":["../../../src/number-field/number-field.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAiBrE;;GAEG;AACH,qBAAa,WAAY,SAAQ,eAAe;IACxC,YAAY,EAAE,MAAM,CAAS;IACnC,OAAO,CAAC,mBAAmB;IAKA,QAAQ,EAAE,OAAO,CAAS;IAC/C,KAAK,EAAE,MAAM,CAAM;IACE,cAAc,EAAE,OAAO,CAAS;IACrD,MAAM,EAAE,MAAM,CAAW;IACJ,iBAAiB,EAAE,OAAO,CAAS;IACxD,qBAAqB,EAAE,MAAM,CAAuB;IAE1D,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAG/B;IAEF,MAAM,IAAI,IAAI;IAuCd,QAAQ,IAAI,IAAI;IA0ChB,2BAA2B;IAK3B,eAAe,IAAI,IAAI;IAoCvB,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IA+C5C,UAAU,IAAI,IAAI;CA4BnB;AAED,eAAO,MAAM,kCAAkC,EAAE,cAGhD,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;CAWpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,oTAMhC,CAAC"}
1
+ {"version":3,"file":"number-field.d.ts","sourceRoot":"","sources":["../../../src/number-field/number-field.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;;;;;;;;;;;AAkBrE;;GAEG;AACH,qBAAa,WAAY,SAAQ,gBAA2B;IACpD,YAAY,EAAE,MAAM,CAAS;IACnC,OAAO,CAAC,mBAAmB;IAKA,QAAQ,EAAE,OAAO,CAAS;IAE/C,KAAK,EAAE,MAAM,CAAM;IACE,cAAc,EAAE,OAAO,CAAS;IACrD,MAAM,EAAE,MAAM,CAAW;IACJ,iBAAiB,EAAE,OAAO,CAAS;IACxD,qBAAqB,EAAE,MAAM,CAAuB;IAE1D,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAG/B;IAEF,MAAM,IAAI,IAAI;IAuCd,QAAQ,IAAI,IAAI;IA0ChB,2BAA2B;IAK3B,eAAe,IAAI,IAAI;IAoCvB,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IA+C5C,UAAU,IAAI,IAAI;CA4BnB;AAED,eAAO,MAAM,kCAAkC,EAAE,cAGhD,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;CAWpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,oTAMhC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"number-field.styles.d.ts","sourceRoot":"","sources":["../../../src/number-field/number-field.styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,2BAA2B,GACtC,SAAS,wBAAwB,EACjC,YAAY,2BAA2B,KACtC,aAkCF,CAAC"}
1
+ {"version":3,"file":"number-field.styles.d.ts","sourceRoot":"","sources":["../../../src/number-field/number-field.styles.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,4BAA4B,CAAC;AAGpC,eAAO,MAAM,2BAA2B,GACtC,SAAS,wBAAwB,EACjC,YAAY,2BAA2B,KACtC,aAgCF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"number-field.template.d.ts","sourceRoot":"","sources":["../../../src/number-field/number-field.template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAGL,yBAAyB,EACzB,kBAAkB,EAEnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,yBAAyB,CACnE,YAAY,CAAC,WAAW,CAAC,EACzB,kBAAkB,CA0EnB,CAAC"}
1
+ {"version":3,"file":"number-field.template.d.ts","sourceRoot":"","sources":["../../../src/number-field/number-field.template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAGL,yBAAyB,EACzB,kBAAkB,EAEnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,yBAAyB,CACnE,YAAY,CAAC,WAAW,CAAC,EACzB,kBAAkB,CA2GnB,CAAC"}
@@ -1,34 +1,23 @@
1
1
  import { TextField as FASTTextField } from '@microsoft/fast-components';
2
+ declare const TextField_base: {
3
+ new (...args: any[]): {
4
+ prefix: string;
5
+ suffix: string;
6
+ hideAffixFromScreenReader: boolean;
7
+ get controlAriaDescribedby(): string | undefined;
8
+ ariaDescribedby: string | null;
9
+ id: string;
10
+ };
11
+ } & typeof FASTTextField;
2
12
  /**
3
13
  * @tagname %%prefix%%-text-field
4
14
  */
5
- export declare class TextField extends FASTTextField {
15
+ export declare class TextField extends TextField_base {
6
16
  autocomplete: string;
7
17
  private autocompleteChanged;
8
18
  autocapitalize: string;
9
19
  private autocapitalizeChanged;
10
20
  step: number;
11
- /**
12
- * Optional non-editable label shown on the left inside the field, before the input.
13
- */
14
- prefix: string;
15
- /**
16
- * Optional non-editable suffix (e.g. unit label) shown on the right inside the field.
17
- */
18
- suffix: string;
19
- /**
20
- * When true, prefix/suffix are not exposed to assistive technology (`aria-hidden` on affixes, and their ids are omitted from the control’s `aria-describedby`).
21
- * Use only when the unit or symbol is redundant with the visible label or other text.
22
- * @remarks
23
- * By default, affix text is **included** for screen readers: stable ids are assigned to the affix nodes and referenced from the input’s `aria-describedby` (merged with any author `aria-describedby`), which announces them as supplementary description after the field name from the label.
24
- * For cases where the affix should be part of the accessible **name** instead (e.g. currency code read as part of the label), set `hide-affix-from-screen-reader` and wire `aria-labelledby` on the host to reference the label slot and your own elements, or provide a single `aria-label` that includes the full name.
25
- */
26
- hideAffixFromScreenReader: boolean;
27
- /**
28
- * Merges the host `aria-describedby` with ids of the prefix/suffix nodes when those affixes are exposed to SRs.
29
- * @internal
30
- */
31
- get controlAriaDescribedby(): string | undefined;
32
21
  }
33
22
  export declare const foundationTextFieldShadowOptions: ShadowRootInit;
34
23
  export declare const defaultTextFieldConfig: {};
@@ -40,4 +29,5 @@ export declare const defaultTextFieldConfig: {};
40
29
  * HTML Element: \<foundation-text-field\>
41
30
  */
42
31
  export declare const foundationTextField: (overrideDefinition?: import("@microsoft/fast-foundation").OverrideFoundationElementDefinition<import("@microsoft/fast-foundation").FoundationElementDefinition>) => import("@microsoft/fast-foundation").FoundationElementRegistry<import("@microsoft/fast-foundation").FoundationElementDefinition, typeof TextField>;
32
+ export {};
43
33
  //# sourceMappingURL=text-field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-field.d.ts","sourceRoot":"","sources":["../../../src/text-field/text-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAOxE;;GAEG;AACH,qBAAa,SAAU,SAAQ,aAAa;IACpC,YAAY,EAAE,MAAM,CAAS;IACnC,OAAO,CAAC,mBAAmB;IAKrB,cAAc,EAAE,MAAM,CAAS;IACrC,OAAO,CAAC,qBAAqB;IAKvB,IAAI,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACG,MAAM,EAAE,MAAM,CAAC;IAErB;;OAEG;IACG,MAAM,EAAE,MAAM,CAAC;IAErB;;;;;;OAMG;IAEH,yBAAyB,EAAE,OAAO,CAAS;IAE3C;;;OAGG;IACH,IAAI,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAyB/C;CACF;AAGD,eAAO,MAAM,gCAAgC,EAAE,cAG9C,CAAC;AAEF,eAAO,MAAM,sBAAsB,IAAK,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,yTAM9B,CAAC"}
1
+ {"version":3,"file":"text-field.d.ts","sourceRoot":"","sources":["../../../src/text-field/text-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;;;;;;;;;;;AAQxE;;GAEG;AACH,qBAAa,SAAU,SAAQ,cAAyB;IAChD,YAAY,EAAE,MAAM,CAAS;IACnC,OAAO,CAAC,mBAAmB;IAKrB,cAAc,EAAE,MAAM,CAAS;IACrC,OAAO,CAAC,qBAAqB;IAKvB,IAAI,EAAE,MAAM,CAAC;CACpB;AAGD,eAAO,MAAM,gCAAgC,EAAE,cAG9C,CAAC;AAEF,eAAO,MAAM,sBAAsB,IAAK,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,yTAM9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"text-field.styles.d.ts","sourceRoot":"","sources":["../../../src/text-field/text-field.styles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAO,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,4BAA4B,CAAC;AAEpC,eAAO,MAAM,yBAAyB,GACpC,SAAS,wBAAwB,EACjC,YAAY,2BAA2B,KACtC,aAmEF,CAAC"}
1
+ {"version":3,"file":"text-field.styles.d.ts","sourceRoot":"","sources":["../../../src/text-field/text-field.styles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAO,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EACV,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,4BAA4B,CAAC;AAGpC,eAAO,MAAM,yBAAyB,GACpC,SAAS,wBAAwB,EACjC,YAAY,2BAA2B,KACtC,aAQF,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { __decorate } from "tslib";
2
+ import { attr } from '@microsoft/fast-element';
3
+ /**
4
+ * Mixin that adds prefix/suffix affix support with screen-reader handling to an input field component.
5
+ * Shared between TextField and NumberField to keep the behaviour consistent and avoid duplication.
6
+ */
7
+ export function AffixMixin(Base) {
8
+ class AffixClass extends Base {
9
+ constructor() {
10
+ super(...arguments);
11
+ /**
12
+ * When true, prefix/suffix are not exposed to assistive technology (`aria-hidden` on affixes,
13
+ * and their ids are omitted from the control's `aria-describedby`).
14
+ * Use only when the unit or symbol is redundant with the visible label or other text.
15
+ * @remarks
16
+ * By default, affix text is **included** for screen readers: stable ids are assigned to the
17
+ * affix nodes and referenced from the input's `aria-describedby` (merged with any author
18
+ * `aria-describedby`), which announces them as supplementary description after the field name
19
+ * from the label.
20
+ * For cases where the affix should be part of the accessible **name** instead (e.g. currency
21
+ * code read as part of the label), set `hide-affix-from-screen-reader` and wire
22
+ * `aria-labelledby` on the host to reference the label slot and your own elements, or provide
23
+ * a single `aria-label` that includes the full name.
24
+ */
25
+ this.hideAffixFromScreenReader = false;
26
+ }
27
+ /**
28
+ * Merges the host `aria-describedby` with ids of the prefix/suffix nodes when those affixes
29
+ * are exposed to screen readers.
30
+ * @internal
31
+ */
32
+ get controlAriaDescribedby() {
33
+ var _a;
34
+ const hostIds = (_a = this.ariaDescribedby) === null || _a === void 0 ? void 0 : _a.trim();
35
+ const parts = [];
36
+ if (hostIds) {
37
+ parts.push(...hostIds.split(/\s+/).filter(Boolean));
38
+ }
39
+ if (!this.hideAffixFromScreenReader) {
40
+ const base = this.id || 'control';
41
+ if (this.prefix) {
42
+ parts.push(`${base}-prefix`);
43
+ }
44
+ if (this.suffix) {
45
+ parts.push(`${base}-suffix`);
46
+ }
47
+ }
48
+ const seen = new Set();
49
+ const deduped = [];
50
+ for (const id of parts) {
51
+ if (!seen.has(id)) {
52
+ seen.add(id);
53
+ deduped.push(id);
54
+ }
55
+ }
56
+ const merged = deduped.join(' ');
57
+ return merged || undefined;
58
+ }
59
+ }
60
+ __decorate([
61
+ attr
62
+ ], AffixClass.prototype, "prefix", void 0);
63
+ __decorate([
64
+ attr
65
+ ], AffixClass.prototype, "suffix", void 0);
66
+ __decorate([
67
+ attr({ attribute: 'hide-affix-from-screen-reader', mode: 'boolean' })
68
+ ], AffixClass.prototype, "hideAffixFromScreenReader", void 0);
69
+ return AffixClass;
70
+ }
@@ -0,0 +1,62 @@
1
+ import { css } from '@microsoft/fast-element';
2
+ export const sharedFieldStyles = css `
3
+ .label-hidden {
4
+ margin: 0;
5
+ }
6
+
7
+ .control-field {
8
+ display: flex;
9
+ flex: 1 1 0%;
10
+ min-width: 0;
11
+ align-self: stretch;
12
+ align-items: stretch;
13
+ }
14
+
15
+ .control-field .control {
16
+ flex: 1 1 auto;
17
+ min-width: 0;
18
+ width: auto;
19
+ }
20
+
21
+ .prefix,
22
+ .suffix {
23
+ display: flex;
24
+ align-items: center;
25
+ flex-shrink: 0;
26
+ box-sizing: border-box;
27
+ padding: 0 calc(var(--design-unit) * 2px);
28
+ user-select: none;
29
+ white-space: nowrap;
30
+ background-color: var(--neutral-fill-rest);
31
+ color: var(--neutral-foreground-hint);
32
+ font-size: var(--type-ramp-base-font-size);
33
+ font-family: inherit;
34
+ line-height: 1;
35
+ }
36
+
37
+ .prefix {
38
+ border-right: 1px solid var(--neutral-stroke-divider-rest);
39
+ border-radius: calc(var(--control-corner-radius) * 1px) 0 0
40
+ calc(var(--control-corner-radius) * 1px);
41
+ }
42
+
43
+ .suffix {
44
+ border-left: 1px solid var(--neutral-stroke-divider-rest);
45
+ border-radius: 0 calc(var(--control-corner-radius) * 1px)
46
+ calc(var(--control-corner-radius) * 1px) 0;
47
+ }
48
+
49
+ :host(.has-prefix:not(.has-suffix)) .control-field .control {
50
+ border-radius: 0 calc(var(--control-corner-radius) * 1px)
51
+ calc(var(--control-corner-radius) * 1px) 0;
52
+ }
53
+
54
+ :host(.has-suffix:not(.has-prefix)) .control-field .control {
55
+ border-radius: calc(var(--control-corner-radius) * 1px) 0 0
56
+ calc(var(--control-corner-radius) * 1px);
57
+ }
58
+
59
+ :host(.has-prefix.has-suffix) .control-field .control {
60
+ border-radius: 0;
61
+ }
62
+ `;
@@ -1,2 +1,4 @@
1
+ export * from './affix-mixin';
1
2
  export * from './base-file-component';
3
+ export * from './field-styles';
2
4
  export * from './icons';
@@ -2,6 +2,7 @@ import { __decorate } from "tslib";
2
2
  import { NumberParser } from '@genesislcap/foundation-utils';
3
3
  import { NumberField as FASTNumberField } from '@microsoft/fast-components';
4
4
  import { DOM, attr } from '@microsoft/fast-element';
5
+ import { AffixMixin } from '../_common';
5
6
  import { foundationNumberFieldStyles as styles } from './number-field.styles';
6
7
  import { foundationNumberFieldTemplate as template } from './number-field.template';
7
8
  import { applyDecimalPrecisionLimits, calculateAutoStepPrecision, decrementWithPrecision, formatControlValue, incrementWithPrecision, toIntlNumberFormat, validateInput, validateMinMax, } from './utils';
@@ -10,7 +11,7 @@ const MAX_INPUT_PRECISION = 12;
10
11
  /**
11
12
  * @tagname %%prefix%%-number-field
12
13
  */
13
- export class NumberField extends FASTNumberField {
14
+ export class NumberField extends AffixMixin(FASTNumberField) {
14
15
  constructor() {
15
16
  super(...arguments);
16
17
  this.autocomplete = 'off';
@@ -1,5 +1,6 @@
1
1
  import { numberFieldStyles as fastNumberFieldStyles } from '@microsoft/fast-components';
2
2
  import { css } from '@microsoft/fast-element';
3
+ import { sharedFieldStyles } from '../_common';
3
4
  export const foundationNumberFieldStyles = (context, definition) => css `
4
5
  ${fastNumberFieldStyles(context, definition)}
5
6
  ::part(label) {
@@ -31,7 +32,5 @@ export const foundationNumberFieldStyles = (context, definition) => css `
31
32
  margin-inline-end: unset;
32
33
  }
33
34
 
34
- .label-hidden {
35
- margin: 0;
36
- }
35
+ ${sharedFieldStyles}
37
36
  `;
@@ -7,7 +7,11 @@ import { endSlotTemplate, startSlotTemplate, } from '@microsoft/fast-foundation'
7
7
  * Taken from `@microsoft/fast-foundation.46.2`
8
8
  */
9
9
  export const foundationNumberFieldTemplate = (context, definition) => html `
10
- <template class="${(x) => (x.readOnly ? 'readonly' : '')}">
10
+ <template
11
+ class="${(x) => [x.readOnly ? 'readonly' : '', x.prefix ? 'has-prefix' : '', x.suffix ? 'has-suffix' : '']
12
+ .filter(Boolean)
13
+ .join(' ')}"
14
+ >
11
15
  <label
12
16
  part="label"
13
17
  for="${(x) => (x.id ? x.id : 'control')}"
@@ -17,51 +21,73 @@ export const foundationNumberFieldTemplate = (context, definition) => html `
17
21
  </label>
18
22
  <div class="root" part="root">
19
23
  ${startSlotTemplate(context, definition)}
20
- <input
21
- class="control"
22
- part="control"
23
- name="${(x) => x.name}"
24
- autocomplete="${(x) => x.autocomplete}"
25
- id="${(x) => (x.id ? x.id : 'control')}"
26
- @input="${(x) => x.handleTextInput()}"
27
- @change="${(x) => x.handleChange()}"
28
- @keydown="${(x, c) => x.handleKeyDown(c.event)}"
29
- @blur="${(x, c) => x.handleBlur()}"
30
- ?autofocus="${(x) => x.autofocus}"
31
- ?disabled="${(x) => x.disabled}"
32
- list="${(x) => x.list}"
33
- maxlength="${(x) => x.maxlength}"
34
- minlength="${(x) => x.minlength}"
35
- placeholder="${(x) => x.placeholder}"
36
- ?readonly="${(x) => x.readOnly}"
37
- ?required="${(x) => x.required}"
38
- size="${(x) => x.size}"
39
- type="text"
40
- inputmode="numeric"
41
- min="${(x) => x.min}"
42
- max="${(x) => x.max}"
43
- step="${(x) => x.step}"
44
- aria-atomic="${(x) => x.ariaAtomic}"
45
- aria-busy="${(x) => x.ariaBusy}"
46
- aria-controls="${(x) => x.ariaControls}"
47
- aria-current="${(x) => x.ariaCurrent}"
48
- aria-describedby="${(x) => x.ariaDescribedby}"
49
- aria-details="${(x) => x.ariaDetails}"
50
- aria-disabled="${(x) => x.ariaDisabled}"
51
- aria-errormessage="${(x) => x.ariaErrormessage}"
52
- aria-flowto="${(x) => x.ariaFlowto}"
53
- aria-haspopup="${(x) => x.ariaHaspopup}"
54
- aria-hidden="${(x) => x.ariaHidden}"
55
- aria-invalid="${(x) => x.ariaInvalid}"
56
- aria-keyshortcuts="${(x) => x.ariaKeyshortcuts}"
57
- aria-label="${(x) => x.ariaLabel}"
58
- aria-labelledby="${(x) => x.ariaLabelledby}"
59
- aria-live="${(x) => x.ariaLive}"
60
- aria-owns="${(x) => x.ariaOwns}"
61
- aria-relevant="${(x) => x.ariaRelevant}"
62
- aria-roledescription="${(x) => x.ariaRoledescription}"
63
- ${ref('control')}
64
- />
24
+ <div class="control-field">
25
+ ${when((x) => x.prefix, html `
26
+ <span
27
+ class="prefix"
28
+ part="prefix"
29
+ id="${(x) => `${x.id || 'control'}-prefix`}"
30
+ ?aria-hidden="${(x) => x.hideAffixFromScreenReader}"
31
+ >
32
+ ${(x) => x.prefix}
33
+ </span>
34
+ `)}
35
+ <input
36
+ class="control"
37
+ part="control"
38
+ name="${(x) => x.name}"
39
+ autocomplete="${(x) => x.autocomplete}"
40
+ id="${(x) => (x.id ? x.id : 'control')}"
41
+ @input="${(x) => x.handleTextInput()}"
42
+ @change="${(x) => x.handleChange()}"
43
+ @keydown="${(x, c) => x.handleKeyDown(c.event)}"
44
+ @blur="${(x, c) => x.handleBlur()}"
45
+ ?autofocus="${(x) => x.autofocus}"
46
+ ?disabled="${(x) => x.disabled}"
47
+ list="${(x) => x.list}"
48
+ maxlength="${(x) => x.maxlength}"
49
+ minlength="${(x) => x.minlength}"
50
+ placeholder="${(x) => x.placeholder}"
51
+ ?readonly="${(x) => x.readOnly}"
52
+ ?required="${(x) => x.required}"
53
+ size="${(x) => x.size}"
54
+ type="text"
55
+ inputmode="numeric"
56
+ min="${(x) => x.min}"
57
+ max="${(x) => x.max}"
58
+ step="${(x) => x.step}"
59
+ aria-atomic="${(x) => x.ariaAtomic}"
60
+ aria-busy="${(x) => x.ariaBusy}"
61
+ aria-controls="${(x) => x.ariaControls}"
62
+ aria-current="${(x) => x.ariaCurrent}"
63
+ aria-describedby="${(x) => x.controlAriaDescribedby}"
64
+ aria-details="${(x) => x.ariaDetails}"
65
+ aria-disabled="${(x) => x.ariaDisabled}"
66
+ aria-errormessage="${(x) => x.ariaErrormessage}"
67
+ aria-flowto="${(x) => x.ariaFlowto}"
68
+ aria-haspopup="${(x) => x.ariaHaspopup}"
69
+ aria-hidden="${(x) => x.ariaHidden}"
70
+ aria-invalid="${(x) => x.ariaInvalid}"
71
+ aria-keyshortcuts="${(x) => x.ariaKeyshortcuts}"
72
+ aria-label="${(x) => x.ariaLabel}"
73
+ aria-labelledby="${(x) => x.ariaLabelledby}"
74
+ aria-live="${(x) => x.ariaLive}"
75
+ aria-owns="${(x) => x.ariaOwns}"
76
+ aria-relevant="${(x) => x.ariaRelevant}"
77
+ aria-roledescription="${(x) => x.ariaRoledescription}"
78
+ ${ref('control')}
79
+ />
80
+ ${when((x) => x.suffix, html `
81
+ <span
82
+ class="suffix"
83
+ part="suffix"
84
+ id="${(x) => `${x.id || 'control'}-suffix`}"
85
+ ?aria-hidden="${(x) => x.hideAffixFromScreenReader}"
86
+ >
87
+ ${(x) => x.suffix}
88
+ </span>
89
+ `)}
90
+ </div>
65
91
  ${when((x) => !x.hideStep && !x.readOnly && !x.disabled, html `
66
92
  <div class="controls" part="controls">
67
93
  <div class="step-up" part="step-up" @click="${(x) => x.stepUp()}">
@@ -1,25 +1,18 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { TextField as FASTTextField } from '@microsoft/fast-components';
3
3
  import { attr } from '@microsoft/fast-element';
4
+ import { AffixMixin } from '../_common';
4
5
  import { foundationTextFieldStyles as styles } from './text-field.styles';
5
6
  import { foundationTextFieldTemplate as template } from './text-field.template';
6
7
  // TODO: Raise a PR against FAST to get autocomplete stuff in place
7
8
  /**
8
9
  * @tagname %%prefix%%-text-field
9
10
  */
10
- export class TextField extends FASTTextField {
11
+ export class TextField extends AffixMixin(FASTTextField) {
11
12
  constructor() {
12
13
  super(...arguments);
13
14
  this.autocomplete = 'off';
14
15
  this.autocapitalize = 'off';
15
- /**
16
- * When true, prefix/suffix are not exposed to assistive technology (`aria-hidden` on affixes, and their ids are omitted from the control’s `aria-describedby`).
17
- * Use only when the unit or symbol is redundant with the visible label or other text.
18
- * @remarks
19
- * By default, affix text is **included** for screen readers: stable ids are assigned to the affix nodes and referenced from the input’s `aria-describedby` (merged with any author `aria-describedby`), which announces them as supplementary description after the field name from the label.
20
- * For cases where the affix should be part of the accessible **name** instead (e.g. currency code read as part of the label), set `hide-affix-from-screen-reader` and wire `aria-labelledby` on the host to reference the label slot and your own elements, or provide a single `aria-label` that includes the full name.
21
- */
22
- this.hideAffixFromScreenReader = false;
23
16
  }
24
17
  autocompleteChanged() {
25
18
  if (this.proxy instanceof HTMLInputElement) {
@@ -31,37 +24,6 @@ export class TextField extends FASTTextField {
31
24
  this.proxy.autocapitalize = this.autocapitalize;
32
25
  }
33
26
  }
34
- /**
35
- * Merges the host `aria-describedby` with ids of the prefix/suffix nodes when those affixes are exposed to SRs.
36
- * @internal
37
- */
38
- get controlAriaDescribedby() {
39
- var _a;
40
- const hostIds = (_a = this.ariaDescribedby) === null || _a === void 0 ? void 0 : _a.trim();
41
- const parts = [];
42
- if (hostIds) {
43
- parts.push(...hostIds.split(/\s+/).filter(Boolean));
44
- }
45
- if (!this.hideAffixFromScreenReader) {
46
- const base = this.id || 'control';
47
- if (this.prefix) {
48
- parts.push(`${base}-prefix`);
49
- }
50
- if (this.suffix) {
51
- parts.push(`${base}-suffix`);
52
- }
53
- }
54
- const seen = new Set();
55
- const deduped = [];
56
- for (const id of parts) {
57
- if (!seen.has(id)) {
58
- seen.add(id);
59
- deduped.push(id);
60
- }
61
- }
62
- const merged = deduped.join(' ');
63
- return merged || undefined;
64
- }
65
27
  }
66
28
  __decorate([
67
29
  attr
@@ -72,15 +34,6 @@ __decorate([
72
34
  __decorate([
73
35
  attr
74
36
  ], TextField.prototype, "step", void 0);
75
- __decorate([
76
- attr
77
- ], TextField.prototype, "prefix", void 0);
78
- __decorate([
79
- attr
80
- ], TextField.prototype, "suffix", void 0);
81
- __decorate([
82
- attr({ attribute: 'hide-affix-from-screen-reader', mode: 'boolean' })
83
- ], TextField.prototype, "hideAffixFromScreenReader", void 0);
84
37
  // explicitly declaring for extensibility
85
38
  export const foundationTextFieldShadowOptions = {
86
39
  mode: 'open',
@@ -1,71 +1,13 @@
1
1
  import { activeColorScheme } from '@genesislcap/foundation-utils';
2
2
  import { textFieldStyles as fastTextFieldStyles } from '@microsoft/fast-components';
3
3
  import { css } from '@microsoft/fast-element';
4
+ import { sharedFieldStyles } from '../_common';
4
5
  export const foundationTextFieldStyles = (context, definition) => css `
5
6
  ${fastTextFieldStyles(context, definition)}
6
-
7
7
  /* Override FAST .root align-items: baseline for this flex child so it still fills the row. */
8
- .control-field {
9
- display: flex;
10
- flex: 1 1 0%;
11
- min-width: 0;
12
- align-self: stretch;
13
- align-items: stretch;
14
- }
15
-
16
- .control-field .control {
17
- flex: 1 1 auto;
18
- min-width: 0;
19
- width: auto;
20
- }
21
-
22
- .prefix,
23
- .suffix {
24
- display: flex;
25
- align-items: center;
26
- flex-shrink: 0;
27
- box-sizing: border-box;
28
- padding: 0 calc(var(--design-unit) * 2px);
29
- user-select: none;
30
- white-space: nowrap;
31
- background-color: var(--neutral-fill-rest);
32
- color: var(--neutral-foreground-hint);
33
- font-size: var(--type-ramp-base-font-size);
34
- font-family: inherit;
35
- line-height: 1;
36
- }
37
-
38
- .prefix {
39
- border-right: 1px solid var(--neutral-stroke-divider-rest);
40
- border-radius: calc(var(--control-corner-radius) * 1px) 0 0
41
- calc(var(--control-corner-radius) * 1px);
42
- }
43
-
44
- .suffix {
45
- border-left: 1px solid var(--neutral-stroke-divider-rest);
46
- border-radius: 0 calc(var(--control-corner-radius) * 1px)
47
- calc(var(--control-corner-radius) * 1px) 0;
48
- }
49
-
50
- :host(.has-prefix:not(.has-suffix)) .control-field .control {
51
- border-radius: 0 calc(var(--control-corner-radius) * 1px)
52
- calc(var(--control-corner-radius) * 1px) 0;
53
- }
54
-
55
- :host(.has-suffix:not(.has-prefix)) .control-field .control {
56
- border-radius: calc(var(--control-corner-radius) * 1px) 0 0
57
- calc(var(--control-corner-radius) * 1px);
58
- }
59
-
60
- :host(.has-prefix.has-suffix) .control-field .control {
61
- border-radius: 0;
62
- }
8
+ ${sharedFieldStyles}
63
9
 
64
10
  input {
65
11
  color-scheme: ${activeColorScheme};
66
12
  }
67
-
68
- .label-hidden {
69
- margin: 0;
70
- }
71
13
  `;