import * as tailwind_variants from 'tailwind-variants'; import { VariantProps } from 'tailwind-variants'; import * as tailwind_merge from 'tailwind-merge'; import * as i0 from '@angular/core'; import { EventEmitter, TemplateRef } from '@angular/core'; import { MnButtonTypes } from 'mn-angular-lib/button'; import { MnActionIcon } from 'mn-angular-lib/forms'; /** * Styling for {@link MnSegmented}, expressed as tailwind-variants slots so the * template pulls one class string per role. * * The control is a track with the active choice raised out of it, rather than a * row of loose buttons: the segments share one bordered surface, so they read as * one control with one answer instead of several independent actions. Theme * tokens only, so it holds up in both light and dark. * * Each segment is an `mnButton`, which owns its own size, colour, radius and * disabled look; the `segment` slot adds only what the button does not know * about — how it sits inside the track. */ declare const mnSegmentedVariants: tailwind_variants.TVReturnType<{ /** * Corner rounding of the track. The segments are rounded one step tighter * (see `SEGMENT_RADIUS` on the component) so a filled segment nests inside * the track's own corner instead of poking out of it. Token names match * mn-button's; `full` makes a pill, where track and segment share the same * fully-rounded ends. */ borderRadius: { none: { root: string; }; xs: { root: string; }; sm: { root: string; }; md: { root: string; }; lg: { root: string; }; xl: { root: string; }; two_xl: { root: string; }; three_xl: { root: string; }; four_xl: { root: string; }; full: { root: string; }; }; /** * Stretch the track and share its width evenly between the segments. * * The segments grow from a zero basis but keep their automatic minimum, so a * justified control inside an auto-width parent still asks for the room its * labels need. Letting them shrink below their content (`min-w-0`) made the * parent resolve to a narrower box and truncated the labels instead. */ justified: { true: { root: string; segment: string; }; false: {}; }; /** * Whether the segment is the picked one. The colours come from the button * itself (a filled primary button when active, a ghost one otherwise); this * only keeps an inactive segment's box the same size as an active one, whose * fill variant carries a real border. */ active: { true: {}; false: { segment: string; }; }; }, { root: string; segment: string; }, undefined, { /** * Corner rounding of the track. The segments are rounded one step tighter * (see `SEGMENT_RADIUS` on the component) so a filled segment nests inside * the track's own corner instead of poking out of it. Token names match * mn-button's; `full` makes a pill, where track and segment share the same * fully-rounded ends. */ borderRadius: { none: { root: string; }; xs: { root: string; }; sm: { root: string; }; md: { root: string; }; lg: { root: string; }; xl: { root: string; }; two_xl: { root: string; }; three_xl: { root: string; }; four_xl: { root: string; }; full: { root: string; }; }; /** * Stretch the track and share its width evenly between the segments. * * The segments grow from a zero basis but keep their automatic minimum, so a * justified control inside an auto-width parent still asks for the room its * labels need. Letting them shrink below their content (`min-w-0`) made the * parent resolve to a narrower box and truncated the labels instead. */ justified: { true: { root: string; segment: string; }; false: {}; }; /** * Whether the segment is the picked one. The colours come from the button * itself (a filled primary button when active, a ghost one otherwise); this * only keeps an inactive segment's box the same size as an active one, whose * fill variant carries a real border. */ active: { true: {}; false: { segment: string; }; }; }, { root: string; segment: string; }, tailwind_variants.TVReturnType<{ /** * Corner rounding of the track. The segments are rounded one step tighter * (see `SEGMENT_RADIUS` on the component) so a filled segment nests inside * the track's own corner instead of poking out of it. Token names match * mn-button's; `full` makes a pill, where track and segment share the same * fully-rounded ends. */ borderRadius: { none: { root: string; }; xs: { root: string; }; sm: { root: string; }; md: { root: string; }; lg: { root: string; }; xl: { root: string; }; two_xl: { root: string; }; three_xl: { root: string; }; four_xl: { root: string; }; full: { root: string; }; }; /** * Stretch the track and share its width evenly between the segments. * * The segments grow from a zero basis but keep their automatic minimum, so a * justified control inside an auto-width parent still asks for the room its * labels need. Letting them shrink below their content (`min-w-0`) made the * parent resolve to a narrower box and truncated the labels instead. */ justified: { true: { root: string; segment: string; }; false: {}; }; /** * Whether the segment is the picked one. The colours come from the button * itself (a filled primary button when active, a ghost one otherwise); this * only keeps an inactive segment's box the same size as an active one, whose * fill variant carries a real border. */ active: { true: {}; false: { segment: string; }; }; }, { root: string; segment: string; }, undefined, unknown, unknown, undefined>>; type MnSegmentedVariants = VariantProps; /** * One choice in a {@link MnSegmented} control. * * A segment is a label, an icon, or both. Icon-only segments carry no visible * text, so they need an {@link ariaLabel} to stay reachable by name. */ type MnSegmentedItem = { /** Value emitted when this segment is picked; also identifies the active one. */ value: string; /** Translation key or literal label. Omit for an icon-only segment. */ label?: string; /** * Optional leading icon: a `TemplateRef` (full control over the icon set — an * ``, an emoji, a bespoke ``) or lucide icon *data* such as * `LucideList.icon`. The same convention the dropdown's actions use; see * {@link MnActionIcon}. */ icon?: MnActionIcon; /** * Accessible name of the segment. Required when {@link label} is omitted, * since an icon alone names nothing; ignored otherwise — the label is the name. */ ariaLabel?: string; /** Whether this choice cannot be picked. Defaults to false. */ disabled?: boolean; }; /** * Data source for {@link MnSegmented}. * * The control is a single-choice switch: exactly one of {@link items} is active * at a time, and which one is decided by the consumer through * {@link MnSegmented.value} rather than by the control itself. */ type MnSegmentedDataSource = { /** The choices, in the order they are shown. Two or three read best. */ items: MnSegmentedItem[]; /** Visual scale. Defaults to `'md'`. */ size?: 'sm' | 'md'; /** * Corner rounding, in mn-button's radius tokens plus `'full'` for a pill. * Defaults to `'lg'`. The segments follow the track one step tighter, so the * active segment stays nested inside the track's corner. */ borderRadius?: MnSegmentedVariants['borderRadius']; /** * Translation key or literal naming what the group switches, e.g. "View". * Without it the group is an unnamed set of buttons to a screen reader. */ ariaLabel?: string; }; /** * A segmented control: two or three mutually exclusive choices sharing one * track, of which exactly one is active — a view switch (list ⇄ calendar), a * scope switch (mine ⇄ everyone), a range switch (week ⇄ month). * * The selection is **controlled**: the component renders whatever * {@link value} says and emits {@link valueChange} on a click, so the consumer's * own state stays the single source of truth for what is on screen. It keeps no * copy of the selection, and — unlike `mn-tab` — it does not mirror one into the * URL, so it can sit on a page that already has a tab bar without the two * fighting over the query string. * * Each segment is an `mnButton` — a filled primary one when active, a ghost one * otherwise — so the control inherits the button's sizes, colours and disabled * look rather than maintaining a parallel set. * * For switching between panes of a page, reach for `mn-tab`; this is for * switching how one pane is rendered. */ declare class MnSegmented { /** The choices and how the group is labelled and scaled. */ dataSource: MnSegmentedDataSource; /** * Value of the active segment. No value (or one naming no segment) leaves the * control with nothing active, which is what an unresolved selection should * look like — the component never picks one on the consumer's behalf. */ value?: string; /** * Whether the segments stretch to fill the available width. Defaults to false, * so the control hugs its content and can be parked at the end of a row; turn * it on where it should span its container, typically on a narrow screen. */ justified: boolean; /** Emits the picked segment's value. The consumer decides what to do with it. */ valueChange: EventEmitter; /** Resolves this control's own accessible names against the app's bundle. */ private readonly lang; /** Resolved slot classes for the current rounding and layout. */ get styles(): { root: (slotProps?: ({ borderRadius?: "lg" | "none" | "xs" | "sm" | "md" | "xl" | "two_xl" | "three_xl" | "four_xl" | "full" | undefined; justified?: boolean | undefined; active?: boolean | undefined; } & tailwind_variants.ClassProp) | undefined) => string; segment: (slotProps?: ({ borderRadius?: "lg" | "none" | "xs" | "sm" | "md" | "xl" | "two_xl" | "three_xl" | "four_xl" | "full" | undefined; justified?: boolean | undefined; active?: boolean | undefined; } & tailwind_variants.ClassProp) | undefined) => string; } & { root: (slotProps?: ({ borderRadius?: "lg" | "none" | "xs" | "sm" | "md" | "xl" | "two_xl" | "three_xl" | "four_xl" | "full" | undefined; justified?: boolean | undefined; active?: boolean | undefined; } & tailwind_variants.ClassProp) | undefined) => string; segment: (slotProps?: ({ borderRadius?: "lg" | "none" | "xs" | "sm" | "md" | "xl" | "two_xl" | "three_xl" | "four_xl" | "full" | undefined; justified?: boolean | undefined; active?: boolean | undefined; } & tailwind_variants.ClassProp) | undefined) => string; } & {}; /** Icon edge length matching the control's text size. */ get iconSize(): number; /** Accessible name of the group, or null when the consumer named nothing. */ get groupLabel(): string | null; /** * Whether `item` is the active choice. * @param item - The segment to test. */ isActive(item: MnSegmentedItem): boolean; /** * Layout classes for one segment — how it sits in the track. Its size, colour, * radius and disabled look come from the button itself; see * {@link segmentButton}. * @param item - The segment to style. */ segmentClass(item: MnSegmentedItem): string; /** * The `mnButton` configuration of one segment: a filled primary button when it * is the active choice, a ghost button otherwise, at the control's size and one * radius step inside the track. The active segment has no hover — re-picking it * does nothing, so nothing should invite the click. * @param item - The segment to configure. */ segmentButton(item: MnSegmentedItem): Partial; /** * Accessible name for an icon-only segment, or null when the segment shows a * label — that label already names it, and a second name would only compete. * @param item - The segment to name. */ segmentLabel(item: MnSegmentedItem): string | null; /** * Whether an icon was supplied as a `TemplateRef` rather than lucide icon data. * @param value - The icon to test. */ isTemplateRef(value: unknown): value is TemplateRef; /** * Announces a click. Re-picking the active segment is silent: it is not a * change, and a consumer that reloads on every emission would refetch for * nothing. * @param item - The segment that was clicked. */ select(item: MnSegmentedItem): void; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } export { MnSegmented, mnSegmentedVariants }; export type { MnSegmentedDataSource, MnSegmentedItem, MnSegmentedVariants };