@nanahoshi/mona-ui 0.16.0 → 0.17.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.
@@ -36,6 +36,12 @@ const segmentedContainerThemeVariants = cva(`
36
36
  transition-colors duration-(--mona-motion-fast)
37
37
  `, {
38
38
  variants: {
39
+ alignment: {
40
+ start: "justify-start",
41
+ center: "justify-center",
42
+ end: "justify-end",
43
+ stretch: "justify-stretch"
44
+ },
39
45
  rounded: {
40
46
  none: "rounded-none",
41
47
  small: "rounded-sm",
@@ -45,11 +51,12 @@ const segmentedContainerThemeVariants = cva(`
45
51
  }
46
52
  },
47
53
  defaultVariants: {
54
+ alignment: "stretch",
48
55
  rounded: "medium"
49
56
  }
50
57
  });
51
58
  const segmentedOptionThemeVariants = cva(`
52
- relative flex flex-1 cursor-pointer items-center justify-center gap-1
59
+ relative flex cursor-pointer items-center justify-center gap-1
53
60
  whitespace-nowrap
54
61
  transition-colors duration-(--mona-motion-fast)
55
62
  data-[disabled='true']:pointer-events-none
@@ -63,6 +70,12 @@ const segmentedOptionThemeVariants = cva(`
63
70
  data-[selected='true']:transition-none
64
71
  `, {
65
72
  variants: {
73
+ alignment: {
74
+ start: "flex-none",
75
+ center: "flex-none",
76
+ end: "flex-none",
77
+ stretch: "flex-1"
78
+ },
66
79
  rounded: {
67
80
  none: "rounded-none",
68
81
  small: "rounded-xs",
@@ -77,6 +90,7 @@ const segmentedOptionThemeVariants = cva(`
77
90
  }
78
91
  },
79
92
  defaultVariants: {
93
+ alignment: "stretch",
80
94
  rounded: "medium",
81
95
  size: "medium"
82
96
  }
@@ -127,7 +141,7 @@ class SegmentedComponent {
127
141
  this.#lastSize = null;
128
142
  this.#resizeObserver = null;
129
143
  this.containerClasses = computed(() => {
130
- const classes = segmentedContainerThemeVariants({ rounded: this.rounded() });
144
+ const classes = segmentedContainerThemeVariants({ alignment: this.alignment(), rounded: this.rounded() });
131
145
  return twMerge(classes, this.userClass());
132
146
  }, /* @ts-ignore */
133
147
  ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
@@ -150,9 +164,10 @@ class SegmentedComponent {
150
164
  ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
151
165
  this.itemTemplate = contentChild(SegmentedItemTemplateDirective, { ...(ngDevMode ? { debugName: "itemTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
152
166
  this.optionClasses = computed(() => {
167
+ const alignment = this.alignment();
153
168
  const rounded = this.rounded();
154
169
  const size = this.size();
155
- return segmentedOptionThemeVariants({ rounded, size });
170
+ return segmentedOptionThemeVariants({ alignment, rounded, size });
156
171
  }, /* @ts-ignore */
157
172
  ...(ngDevMode ? [{ debugName: "optionClasses" }] : /* istanbul ignore next */ []));
158
173
  this.optionElements = viewChildren("optionElement", /* @ts-ignore */
@@ -171,6 +186,12 @@ class SegmentedComponent {
171
186
  return this.disabled() || !!option?.disabled;
172
187
  }, /* @ts-ignore */
173
188
  ...(ngDevMode ? [{ debugName: "selectedOptionDisabled" }] : /* istanbul ignore next */ []));
189
+ /**
190
+ * @description Controls the alignment of the items inside the segmented component.
191
+ * @default "stretch"
192
+ */
193
+ this.alignment = input("stretch", /* @ts-ignore */
194
+ ...(ngDevMode ? [{ debugName: "alignment" }] : /* istanbul ignore next */ []));
174
195
  /**
175
196
  * @description Controls whether the selection indicator animates between selected options.
176
197
  * When false, selection changes are applied immediately without transition.
@@ -245,6 +266,7 @@ class SegmentedComponent {
245
266
  read: () => {
246
267
  this.selectedIndex();
247
268
  this.optionElements();
269
+ this.alignment();
248
270
  this.rounded();
249
271
  this.animate();
250
272
  const size = this.size();
@@ -335,7 +357,7 @@ class SegmentedComponent {
335
357
  }
336
358
  }
337
359
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
338
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SegmentedComponent, isStandalone: true, selector: "mona-segmented", inputs: { animate: { classPropertyName: "animate", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touch: "touch", value: "valueChange" }, host: { properties: { "attr.aria-disabled": "disabled() || undefined", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledBy()", "attr.data-disabled": "disabled()", "attr.data-invalid": "invalidState() || null", "attr.role": "'radiogroup'", "class": "containerClasses()" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: SegmentedItemTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "optionElements", predicate: ["optionElement"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (indicatorGeometry(); as geometry) {\n <div\n aria-hidden=\"true\"\n [class]=\"indicatorClasses()\"\n [attr.data-disabled]=\"selectedOptionDisabled() ? 'true' : null\"\n [style.transform]=\"geometry.transform\"\n [style.width.px]=\"geometry.width\"\n [style.height.px]=\"geometry.height\"></div>\n}\n\n@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label\n #optionElement\n [class]=\"optionClasses()\"\n [attr.data-selected]=\"selected\"\n [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"createOptionContext(option, $index)\"></ng-container>\n } @else {\n {{ option.label }}\n }\n </span>\n </label>\n}\n\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
360
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SegmentedComponent, isStandalone: true, selector: "mona-segmented", inputs: { alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, animate: { classPropertyName: "animate", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { touch: "touch", value: "valueChange" }, host: { properties: { "attr.aria-disabled": "disabled() || undefined", "attr.aria-invalid": "invalidState() ? 'true' : null", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledBy()", "attr.data-disabled": "disabled()", "attr.data-invalid": "invalidState() || null", "attr.role": "'radiogroup'", "class": "containerClasses()" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: SegmentedItemTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "optionElements", predicate: ["optionElement"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (indicatorGeometry(); as geometry) {\n <div\n aria-hidden=\"true\"\n [class]=\"indicatorClasses()\"\n [attr.data-disabled]=\"selectedOptionDisabled() ? 'true' : null\"\n [style.transform]=\"geometry.transform\"\n [style.width.px]=\"geometry.width\"\n [style.height.px]=\"geometry.height\"></div>\n}\n\n@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label\n #optionElement\n [class]=\"optionClasses()\"\n [attr.data-selected]=\"selected\"\n [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"createOptionContext(option, $index)\"></ng-container>\n } @else {\n {{ option.label }}\n }\n </span>\n </label>\n}\n\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
339
361
  }
340
362
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SegmentedComponent, decorators: [{
341
363
  type: Component,
@@ -349,7 +371,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
349
371
  "[attr.role]": "'radiogroup'",
350
372
  "[class]": "containerClasses()"
351
373
  }, template: "@if (indicatorGeometry(); as geometry) {\n <div\n aria-hidden=\"true\"\n [class]=\"indicatorClasses()\"\n [attr.data-disabled]=\"selectedOptionDisabled() ? 'true' : null\"\n [style.transform]=\"geometry.transform\"\n [style.width.px]=\"geometry.width\"\n [style.height.px]=\"geometry.height\"></div>\n}\n\n@for (option of options(); track option.value) {\n @let selected = option.value === value();\n @let optionDisabled = disabled() || option.disabled;\n\n <label\n #optionElement\n [class]=\"optionClasses()\"\n [attr.data-selected]=\"selected\"\n [attr.data-disabled]=\"optionDisabled\">\n <input\n type=\"radio\"\n [name]=\"groupName\"\n [value]=\"option.value\"\n [checked]=\"selected\"\n [disabled]=\"optionDisabled\"\n [class]=\"inputClasses()\"\n (change)=\"onOptionChange(option)\"\n (blur)=\"onOptionBlur()\" />\n\n <span\n class=\"pointer-events-none flex flex-1 items-center justify-center gap-1\n [border-radius:inherit]\n peer-focus-visible:ring-2\n peer-focus-visible:ring-focus-indicator/35\">\n @if (itemTemplate(); as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"createOptionContext(option, $index)\"></ng-container>\n } @else {\n {{ option.label }}\n }\n </span>\n </label>\n}\n\n" }]
352
- }], ctorParameters: () => [], propDecorators: { itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SegmentedItemTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], optionElements: [{ type: i0.ViewChildren, args: ["optionElement", { isSignal: true }] }], animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
374
+ }], ctorParameters: () => [], propDecorators: { itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SegmentedItemTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], optionElements: [{ type: i0.ViewChildren, args: ["optionElement", { isSignal: true }] }], alignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignment", required: false }] }], animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
353
375
 
354
376
  /*
355
377
  * Public API Surface of @nanahoshi/mona-ui/segmented
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanahoshi/mona-ui",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "A very light Angular UI framework",
5
5
  "author": "Nanahoshi",
6
6
  "repository": {
@@ -47,9 +47,11 @@ interface SegmentedItemTemplateContext<T extends SegmentedValue = SegmentedValue
47
47
  }
48
48
 
49
49
  declare const segmentedContainerThemeVariants: (props?: ({
50
+ alignment?: "start" | "center" | "end" | "stretch" | null | undefined;
50
51
  rounded?: "none" | "small" | "medium" | "large" | "full" | null | undefined;
51
52
  } & class_variance_authority_types.ClassProp) | undefined) => string;
52
53
  declare const segmentedOptionThemeVariants: (props?: ({
54
+ alignment?: "start" | "center" | "end" | "stretch" | null | undefined;
53
55
  rounded?: "none" | "small" | "medium" | "large" | "full" | null | undefined;
54
56
  size?: "small" | "medium" | "large" | null | undefined;
55
57
  } & class_variance_authority_types.ClassProp) | undefined) => string;
@@ -75,6 +77,11 @@ declare class SegmentedComponent<T extends SegmentedValue = SegmentedValue> impl
75
77
  protected readonly optionElements: _angular_core.Signal<readonly ElementRef<HTMLLabelElement>[]>;
76
78
  protected readonly selectedIndex: _angular_core.Signal<number>;
77
79
  protected readonly selectedOptionDisabled: _angular_core.Signal<boolean>;
80
+ /**
81
+ * @description Controls the alignment of the items inside the segmented component.
82
+ * @default "stretch"
83
+ */
84
+ readonly alignment: _angular_core.InputSignal<"start" | "center" | "end" | "stretch" | null | undefined>;
78
85
  /**
79
86
  * @description Controls whether the selection indicator animates between selected options.
80
87
  * When false, selection changes are applied immediately without transition.
@@ -144,7 +151,7 @@ declare class SegmentedComponent<T extends SegmentedValue = SegmentedValue> impl
144
151
  private setupResizeObserver;
145
152
  private updateIndicatorGeometry;
146
153
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedComponent<any>, never>;
147
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedComponent<any>, "mona-segmented", never, { "animate": { "alias": "animate"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "touch": "touch"; "value": "valueChange"; }, ["itemTemplate"], never, true, never>;
154
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedComponent<any>, "mona-segmented", never, { "alignment": { "alias": "alignment"; "required": false; "isSignal": true; }; "animate": { "alias": "animate"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "touch": "touch"; "value": "valueChange"; }, ["itemTemplate"], never, true, never>;
148
155
  }
149
156
 
150
157
  /**