From 03ab21703d58865b3cfa6a8df78f22e103cefca3 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Tue, 2 Sep 2025 11:22:34 +0200 Subject: [PATCH 01/13] Add CSS --- src/components/index.css | 1 + src/components/segmented-control.css | 129 +++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/components/segmented-control.css diff --git a/src/components/index.css b/src/components/index.css index 58d63e1b..ca8ddd0a 100644 --- a/src/components/index.css +++ b/src/components/index.css @@ -14,6 +14,7 @@ @import 'modal'; @import 'navbar'; @import 'pagination'; +@import 'segmented-control'; @import 'sidebar'; @import 'side_panel'; @import 'spinner'; diff --git a/src/components/segmented-control.css b/src/components/segmented-control.css new file mode 100644 index 00000000..60b19616 --- /dev/null +++ b/src/components/segmented-control.css @@ -0,0 +1,129 @@ +.segmented-control { + --op-input-inner-focus: 0 0 0 var(--op-border-width-large); + --op-input-focus-primary: var(--op-input-inner-focus) var(--op-color-primary-plus-two), + var(--op-input-outer-focus) var(--op-color-primary-plus-five); + + /* Public API (customizable component options) */ + --_op-segmented-control-height-small: var(--op-input-height-small); + --_op-segmented-control-height-medium: var(--op-input-height-medium); + --_op-segmented-control-height-large: var(--op-input-height-large); + + --_op-segmented-control-font-small: var(--op-font-x-small); + --_op-segmented-control-font-medium: var(--op-font-small); + --_op-segmented-control-font-large: var(--op-font-small); + + --_op-segmented-control-label-padding-small: var(--op-space-x-small); + --_op-segmented-control-label-padding-medium: var(--op-space-small); + --_op-segmented-control-label-padding-large: var(--op-space-small); + + --_op-segmented-control-label-gap-small: var(--op-space-3x-small); + --_op-segmented-control-label-gap-medium: var(--op-space-2x-small); + --_op-segmented-control-label-gap-large: var(--op-space-2x-small); + + --_op-segmented-control-color-icon-default: var(--op-color-neutral-on-plus-eight-alt); + --_op-segmented-control-color-icon-active: light-dark( + var(--op-color-primary-plus-four), + var(--op-color-primary-minus-six) + ); + + /* Private API (component option defaults) */ + --__op-segmented-control-height: var(--_op-segmented-control-height-large); + --__op-segmented-control-font-size: var(--_op-segmented-control-font-large); + --__op-segmented-control-label-padding: var(--_op-segmented-control-label-padding-large); + --__op-segmented-control-label-gap: var(--_op-segmented-control-label-gap-large); + --__op-segmented-control-color-icon: var(--_op-segmented-control-color-icon-default); + + position: relative; + display: grid; + width: fit-content; + height: var(--__op-segmented-control-height); + padding: var(--op-space-2x-small); + border-radius: var(--op-radius-medium); + background-color: var(--op-color-neutral-plus-eight); + box-shadow: var(--op-border-all) var(--op-color-border); + color: var(--op-color-neutral-on-plus-eight); + font-size: var(--__op-segmented-control-font-size); + gap: var(--op-space-2x-small); + grid-auto-flow: column; + + .icon { + color: var(--__op-segmented-control-color-icon); + } + + .segmented-control__input { + position: absolute; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + border-width: 0; + margin: -1px; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + + /* Selected Option */ + &:checked + .segmented-control__label { + --__op-segmented-control-color-icon: var(--_op-segmented-control-color-icon-active); + + background-color: var(--op-color-primary-plus-one); + color: var(--op-color-primary-on-plus-one); + } + + &:focus-visible { + + .segmented-control__label { + box-shadow: var(--op-input-focus-primary); + } + } + } + + .segmented-control__label { + display: inline-flex; + border-radius: var(--op-radius-small); + gap: var(--__op-segmented-control-label-gap); + padding-inline: var(--__op-segmented-control-label-padding); + place-items: center; + white-space: nowrap; + + &:hover { + background-color: var(--op-color-neutral-plus-five); + color: var(--op-color-neutral-on-plus-five); + } + } + + /* Size Modifiers */ + &.segmented-control--small { + --__op-segmented-control-height: var(--_op-segmented-control-height-small); + --__op-segmented-control-font-size: var(--_op-segmented-control-font-small); + --__op-segmented-control-label-padding: var(--_op-segmented-control-label-padding-small); + --__op-segmented-control-label-gap: var(--_op-segmented-control-label-gap-small); + + .icon { + --__op-icon-font-size: var(--_op-icon-font-size-small); + --__op-icon-optical-size: var(--_op-icon-optical-size-small); + } + } + + &.segmented-control--medium { + --__op-segmented-control-height: var(--_op-segmented-control-height-medium); + --__op-segmented-control-font-size: var(--_op-segmented-control-font-medium); + --__op-segmented-control-label-padding: var(--_op-segmented-control-label-padding-medium); + --__op-segmented-control-label-gap: var(--_op-segmented-control-label-gap-medium); + + .icon { + --__op-icon-font-size: var(--_op-icon-font-size-medium); + --__op-icon-optical-size: var(--_op-icon-optical-size-medium); + } + } + + &.segmented-control--large { + --__op-segmented-control-height: var(--_op-segmented-control-height-large); + --__op-segmented-control-font-size: var(--_op-segmented-control-font-large); + --__op-segmented-control-label-padding: var(--_op-segmented-control-label-padding-large); + --__op-segmented-control-label-gap: var(--_op-segmented-control-label-gap-large); + + .icon { + --__op-icon-font-size: var(--_op-icon-font-size-medium); + --__op-icon-optical-size: var(--_op-icon-optical-size-medium); + } + } +} From 7ccbe9155c815bbe8e3d30b6f62feacd88fff2f1 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Tue, 2 Sep 2025 12:08:30 +0200 Subject: [PATCH 02/13] update component template to include source code link --- tools/templates/component/??name??(pascalCase).mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/templates/component/??name??(pascalCase).mdx b/tools/templates/component/??name??(pascalCase).mdx index 20e05d48..89c771b6 100644 --- a/tools/templates/component/??name??(pascalCase).mdx +++ b/tools/templates/component/??name??(pascalCase).mdx @@ -1,5 +1,6 @@ import { Meta, Story, Canvas, Controls } from '@storybook/blocks' import * as ??name??(pascalCase)Stories from './??name??(pascalCase).stories' +import { createSourceCodeLink } from '../../helpers/sourceCodeLink.js' import { createAlert } from '../Alert/Alert.js' @@ -7,6 +8,12 @@ import { createAlert } from '../Alert/Alert.js' # ??name??(pascalCase) +
+ Brief overview description of how to use ??name??(pascalCase) classes ## Playground From a8fa2c0923b6da606de177b4a05cb776de58fd83 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Tue, 2 Sep 2025 12:10:59 +0200 Subject: [PATCH 03/13] Update dependency graphic to be flipped --- tools/generate-graph.dot | 82 +++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/tools/generate-graph.dot b/tools/generate-graph.dot index f8a7583e..6ddb6536 100755 --- a/tools/generate-graph.dot +++ b/tools/generate-graph.dot @@ -5,48 +5,42 @@ digraph dependencies { node [shape = box;]; "Fonts, Tokens, Base"; - "Accordion" -> "Fonts, Tokens, Base"; - "Accordion" -> "Icon"; - - "Alert" -> "Fonts, Tokens, Base"; - "Alert" -> "Icon"; - - "Badge" -> "Fonts, Tokens, Base"; - "Badge" -> "Icon"; - - "Button" -> "Fonts, Tokens, Base"; - "Button" -> "Icon"; - - "Tag" -> "Fonts, Tokens, Base"; - "Tag" -> "Icon"; - - "Button Group" -> "Fonts, Tokens, Base"; - "Button Group" -> "Button"; - - "Sidebar" -> "Fonts, Tokens, Base"; - "Sidebar" -> "Button"; - - "Navbar" -> "Fonts, Tokens, Base"; - "Navbar" -> "Button"; - - "Pagination" -> "Button"; - "Pagination" -> "Form"; - "Pagination" -> "Fonts, Tokens, Base"; - - "Avatar" -> "Fonts, Tokens, Base"; - "Breadcrumbs" -> "Fonts, Tokens, Base"; - "Card" -> "Fonts, Tokens, Base"; - "Content-Header" -> "Fonts, Tokens, Base"; - "Confirm Dialog" -> "Fonts, Tokens, Base"; - "Divider" -> "Fonts, Tokens, Base"; - "Form" -> "Fonts, Tokens, Base"; - "Icon" -> "Fonts, Tokens, Base"; - "Modal" -> "Fonts, Tokens, Base"; - "Side Panel" -> "Fonts, Tokens, Base"; - "Spinner" -> "Fonts, Tokens, Base"; - "Switch" -> "Fonts, Tokens, Base"; - "Tab" -> "Fonts, Tokens, Base"; - "Table" -> "Fonts, Tokens, Base"; - "Text Pair" -> "Fonts, Tokens, Base"; - "Tooltip" -> "Fonts, Tokens, Base"; + "Fonts, Tokens, Base" -> "Accordion"; + "Fonts, Tokens, Base" -> "Alert"; + "Fonts, Tokens, Base" -> "Avatar"; + "Fonts, Tokens, Base" -> "Badge"; + "Fonts, Tokens, Base" -> "Breadcrumbs"; + "Fonts, Tokens, Base" -> "Button"; + "Fonts, Tokens, Base" -> "Button Group"; + "Fonts, Tokens, Base" -> "Card"; + "Fonts, Tokens, Base" -> "Content-Header"; + "Fonts, Tokens, Base" -> "Confirm Dialog"; + "Fonts, Tokens, Base" -> "Divider"; + "Fonts, Tokens, Base" -> "Form"; + "Fonts, Tokens, Base" -> "Icon"; + "Fonts, Tokens, Base" -> "Modal"; + "Fonts, Tokens, Base" -> "Navbar"; + "Fonts, Tokens, Base" -> "Pagination"; + "Fonts, Tokens, Base" -> "Sidebar"; + "Fonts, Tokens, Base" -> "Side Panel"; + "Fonts, Tokens, Base" -> "Spinner"; + "Fonts, Tokens, Base" -> "Switch"; + "Fonts, Tokens, Base" -> "Tab"; + "Fonts, Tokens, Base" -> "Table"; + "Fonts, Tokens, Base" -> "Tag"; + "Fonts, Tokens, Base" -> "Text Pair"; + "Fonts, Tokens, Base" -> "Tooltip"; + + "Icon" -> "Accordion"; + "Icon" -> "Alert"; + "Icon" -> "Badge"; + "Icon" -> "Button"; + "Icon" -> "Tag"; + + "Button" -> "Button Group"; + "Button" -> "Sidebar"; + "Button" -> "Navbar"; + "Button" -> "Pagination"; + + "Form" -> "Pagination"; } From 425b9ff5b36255f6c50dc1ebb02bfbb235090800 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Tue, 2 Sep 2025 12:11:35 +0200 Subject: [PATCH 04/13] Add segmented control documentation story and playground generator --- .../SegmentedControl/SegmentedControl.js | 53 +++++++++++++++++++ .../SegmentedControl.stories.js | 39 ++++++++++++++ tools/generate-graph.dot | 1 + 3 files changed, 93 insertions(+) create mode 100644 src/stories/Components/SegmentedControl/SegmentedControl.js create mode 100644 src/stories/Components/SegmentedControl/SegmentedControl.stories.js diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.js b/src/stories/Components/SegmentedControl/SegmentedControl.js new file mode 100644 index 00000000..307d93fb --- /dev/null +++ b/src/stories/Components/SegmentedControl/SegmentedControl.js @@ -0,0 +1,53 @@ +import { createIcon } from '../Icon/Icon.js' + +const createOptionInput = (index) => { + const element = document.createElement('input') + element.className = 'segmented-control__input' + element.type = 'radio' + element.id = `option-${index}` + element.value = `value ${index}` + element.name = 'example-segmented-control' + + return element +} + +const createOptionLabel = (index, showPrefixIcon, showSuffixIcon) => { + const element = document.createElement('label') + element.className = 'segmented-control__label' + element.setAttribute('for', `option-${index}`) + element.textContent = `Option ${index}` + + if (showPrefixIcon) { + element.prepend(createIcon({ name: 'bolt' })) + } + + if (showSuffixIcon) { + element.appendChild(createIcon({ name: 'info' })) + } + + return element +} + +export const createSegmentedControl = ({ + size = 'large', + showPrefixIcon = false, + showSuffixIcon = false, + options = 3, +}) => { + const element = document.createElement('div') + element.role = 'radiogroup' + + element.className = ['segmented-control', size === 'large' ? '' : `segmented-control--${size}`] + .filter(Boolean) + .join(' ') + + for (let i = 1; i <= options; i++) { + const input = createOptionInput(i) + const label = createOptionLabel(i, showPrefixIcon, showSuffixIcon) + + element.appendChild(input) + element.appendChild(label) + } + + return element +} diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.stories.js b/src/stories/Components/SegmentedControl/SegmentedControl.stories.js new file mode 100644 index 00000000..793fa1b3 --- /dev/null +++ b/src/stories/Components/SegmentedControl/SegmentedControl.stories.js @@ -0,0 +1,39 @@ +import { createSegmentedControl } from './SegmentedControl.js' + +export default { + title: 'Components/Segmented Control', + render: ({ size, ...args }) => { + return createSegmentedControl({ size, ...args }) + }, + argTypes: { + size: { + control: { type: 'select' }, + options: ['small', 'medium', 'large'], + }, + options: { control: 'number' }, + showPrefixIcon: { + control: 'boolean', + description: 'This is not a class. It just provides an example of using icons within the options', + }, + showSuffixIcon: { + control: 'boolean', + description: 'This is not a class. It just provides an example of using icons within the options', + }, + }, +} + +export const Default = { + args: { + showPrefixIcon: false, + showSuffixIcon: false, + options: 3, + size: 'medium', + }, +} + +export const Size = { + args: { + label: 'Small', + size: 'small', + }, +} diff --git a/tools/generate-graph.dot b/tools/generate-graph.dot index 6ddb6536..35fd542f 100755 --- a/tools/generate-graph.dot +++ b/tools/generate-graph.dot @@ -21,6 +21,7 @@ digraph dependencies { "Fonts, Tokens, Base" -> "Modal"; "Fonts, Tokens, Base" -> "Navbar"; "Fonts, Tokens, Base" -> "Pagination"; + "Fonts, Tokens, Base" -> "Segmented Control"; "Fonts, Tokens, Base" -> "Sidebar"; "Fonts, Tokens, Base" -> "Side Panel"; "Fonts, Tokens, Base" -> "Spinner"; From 5b7fc2f6464f33e910241ce9a9f0256a01360357 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Tue, 2 Sep 2025 12:12:16 +0200 Subject: [PATCH 05/13] Add documentation for segmented control --- .../SegmentedControl/SegmentedControl.mdx | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/stories/Components/SegmentedControl/SegmentedControl.mdx diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.mdx b/src/stories/Components/SegmentedControl/SegmentedControl.mdx new file mode 100644 index 00000000..b5042750 --- /dev/null +++ b/src/stories/Components/SegmentedControl/SegmentedControl.mdx @@ -0,0 +1,119 @@ +import { Meta, Story, Canvas, Controls } from '@storybook/addon-docs/blocks' +import * as SegmentedControlStories from './SegmentedControl.stories' +import { createSourceCodeLink } from '../../helpers/sourceCodeLink.js' + +import { createAlert } from '../Alert/Alert.js' + + + +{/* TODO: Add generator for SimpleForm and finish documentation */} + +# Segmented Control + +
+ +Segmented Control classes can be used to create a stylized radio select group. + +## Note on Implementation + +This is just a styling pattern that builds on standard radio inputs and labels. Your project may need some tooling to generate this easily. + +A commonly used tool for Ruby on Rails projects is [SimpleForm](https://github.com/heartcombo/simple_form). It allows you to build forms with pre-made inputs and allows you to make custom input types. + +[RoleModel Rails SimpleForm Generator](https://github.com/RoleModel/rolemodel_rails/tree/master/lib/generators/rolemodel/simple_form) provides a generator to install a custom segmented control input that can be used with SimpleForm with Optics classes applied. + +## Playground + + + + +### Selective Imports + +SegmentedControl can be used as a standalone component, however, it does have a few dependencies. To see a full dependency list, see [Dependency Graph](?path=/docs/overview-selective-imports--docs#dependencies) + +```css +/* Depends on */ +@import '@rolemodel/optics/dist/css/core/fonts'; +@import '@rolemodel/optics/dist/css/core/tokens'; +@import '@rolemodel/optics/dist/css/core/base'; +@import '@rolemodel/optics/dist/css/components/icon'; + +/* Component */ +@import '@rolemodel/optics/dist/css/components/button'; +``` + +## Variations + +### Default + +Description of the default example + + + +### Alternate + +Description of alternate example + + + +## SegmentedControl API + +Styles are built on css variables scoped to the segmentedcontrol. + +Here are the variables that can be customized. + +{/* prettier-ignore-start */} +```css +--_op- +``` +{/* prettier-ignore-end */} + +## Customizing SegmentedControl styles + +
+ +The segmentedcontrol classes are structured using the [BEM methodology](https://getbem.com/naming). + +This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all segmentedcontrol behavior by overriding the `.segmentedcontrol` placeholder selector and setting any properties: + +```css +.segmentedcontrol { +} +``` + +If you need to override the behavior of a particular segmentedcontrol modifier, you can open the respective class and set or change properties + +```css +.segmentedcontrol--modifier { +} +``` + +## New SegmentedControl Variations + +
+ +Your application may need a variation. To add one, just follow this template. Note the double hyphen, indicating that this is a [modifier](https://getbem.com/naming/#modifier): + +```css +.segmentedcontrol--{name} { + @extend %segmentedcontrol-global; +} +``` From 288a3a62d5b6c2c351a505b540ea671e6bef5375 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Sun, 2 Nov 2025 18:51:25 -0500 Subject: [PATCH 06/13] fixup ecd03a6f931b641740234207fbd50d5963ff9c8c --- src/components/segmented-control.css | 3 +- .../SegmentedControl/SegmentedControl.js | 14 +++- .../SegmentedControl/SegmentedControl.mdx | 79 +++++++++++++++---- .../SegmentedControl.stories.js | 6 ++ 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/components/segmented-control.css b/src/components/segmented-control.css index 60b19616..cc1039ad 100644 --- a/src/components/segmented-control.css +++ b/src/components/segmented-control.css @@ -1,6 +1,7 @@ .segmented-control { --op-input-inner-focus: 0 0 0 var(--op-border-width-large); - --op-input-focus-primary: var(--op-input-inner-focus) var(--op-color-primary-plus-two), + --op-input-focus-primary: + var(--op-input-inner-focus) var(--op-color-primary-plus-two), var(--op-input-outer-focus) var(--op-color-primary-plus-five); /* Public API (customizable component options) */ diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.js b/src/stories/Components/SegmentedControl/SegmentedControl.js index 307d93fb..8ea7cbe1 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.js +++ b/src/stories/Components/SegmentedControl/SegmentedControl.js @@ -15,14 +15,20 @@ const createOptionLabel = (index, showPrefixIcon, showSuffixIcon) => { const element = document.createElement('label') element.className = 'segmented-control__label' element.setAttribute('for', `option-${index}`) - element.textContent = `Option ${index}` + element.innerHTML += '\n' if (showPrefixIcon) { - element.prepend(createIcon({ name: 'bolt' })) + element.innerHTML += ' ' + element.appendChild(createIcon({ name: 'bolt' })) + element.innerHTML += '\n' } + element.innerHTML += ` Option ${index} \n ` + if (showSuffixIcon) { + element.innerHTML += ' ' element.appendChild(createIcon({ name: 'info' })) + element.innerHTML += '\n ' } return element @@ -45,9 +51,13 @@ export const createSegmentedControl = ({ const input = createOptionInput(i) const label = createOptionLabel(i, showPrefixIcon, showSuffixIcon) + element.innerHTML += '\n ' element.appendChild(input) + element.innerHTML += '\n ' element.appendChild(label) } + element.innerHTML += '\n' + return element } diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.mdx b/src/stories/Components/SegmentedControl/SegmentedControl.mdx index b5042750..c6bfb5c7 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.mdx +++ b/src/stories/Components/SegmentedControl/SegmentedControl.mdx @@ -43,36 +43,70 @@ SegmentedControl can be used as a standalone component, however, it does have a @import '@rolemodel/optics/dist/css/components/icon'; /* Component */ -@import '@rolemodel/optics/dist/css/components/button'; +@import '@rolemodel/optics/dist/css/components/segmented-control'; ``` ## Variations ### Default -Description of the default example +`.segmented-control` Provides styled radio select group. -### Alternate +### Input -Description of alternate example +`.segmented-control__input` can be used on the radio inputs. + +### Label + +`.segmented-control__label` can be used on the radio labels. + +The [Icon](?path=/docs/content-components-icon--docs) component can be used within the label as a prefix or suffix and will follow the sizing appropriately. + + + +### Size + +`.segmented-control--small`, `.segmented-control--medium`, `.segmented-control--large` (with large being the default) modify the size of any other segmented control class by changing the font, padding, and height to be smaller or larger. ## SegmentedControl API -Styles are built on css variables scoped to the segmentedcontrol. +Styles are built on css variables scoped to the segmented control. Here are the variables that can be customized. {/* prettier-ignore-start */} ```css ---_op- +/* Some global tokens are overridden within this component */ +--op-input-inner-focus +--op-input-focus-primary + +/* Public API (customizable component options) */ +--_op-segmented-control-height-small +--_op-segmented-control-height-medium +--_op-segmented-control-height-large + +--_op-segmented-control-font-small +--_op-segmented-control-font-medium +--_op-segmented-control-font-large + +--_op-segmented-control-label-padding-small +--_op-segmented-control-label-padding-medium +--_op-segmented-control-label-padding-large + +--_op-segmented-control-label-gap-small +--_op-segmented-control-label-gap-medium +--_op-segmented-control-label-gap-large + +--_op-segmented-control-color-icon-default +--_op-segmented-control-color-icon-active ``` {/* prettier-ignore-end */} -## Customizing SegmentedControl styles +## Customizing Segmented Control styles
-The segmentedcontrol classes are structured using the [BEM methodology](https://getbem.com/naming). +The segmented control classes are structured using the [BEM methodology](https://getbem.com/naming). -This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all segmentedcontrol behavior by overriding the `.segmentedcontrol` placeholder selector and setting any properties: +This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all segmented control behavior by overriding the `.segmented-control` class and setting any properties: ```css -.segmentedcontrol { +.segmented-control { + color: red; } ``` -If you need to override the behavior of a particular segmentedcontrol modifier, you can open the respective class and set or change properties +If you need to override the behavior of a particular segmented control modifier, you can open the respective class and set or change properties ```css -.segmentedcontrol--modifier { +.segmented-control--small { + color: red; } ``` -## New SegmentedControl Variations +## New Segmented Control Variations
Date: Sun, 2 Nov 2025 18:46:45 -0500 Subject: [PATCH 07/13] Fix incorrect documentation --- src/stories/Components/ContentHeader/ContentHeader.mdx | 2 +- src/stories/Components/Form/Form.mdx | 4 +--- src/stories/Components/Tag/Tag.mdx | 2 +- tools/templates/component/??name??(pascalCase).mdx | 5 +++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/stories/Components/ContentHeader/ContentHeader.mdx b/src/stories/Components/ContentHeader/ContentHeader.mdx index 918903c5..24828a96 100644 --- a/src/stories/Components/ContentHeader/ContentHeader.mdx +++ b/src/stories/Components/ContentHeader/ContentHeader.mdx @@ -88,7 +88,7 @@ This example demonstrates a content header with minimal customization achieving The content header classes are structured using the [BEM methodology](https://getbem.com/naming). -This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all content header behavior by overriding the `.content-header` placeholder selector and setting any properties: +This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all content header behavior by overriding the `.content-header` class and setting any properties: ```css .content-header { diff --git a/src/stories/Components/Form/Form.mdx b/src/stories/Components/Form/Form.mdx index a3851e9c..81ebe2f9 100644 --- a/src/stories/Components/Form/Form.mdx +++ b/src/stories/Components/Form/Form.mdx @@ -183,9 +183,7 @@ The form classes are structured using the [BEM methodology](https://getbem.com/n This allows multiple classes to share the same behavior. -Form Controls use multiple placeholder selectors to style all types of controls. - -`.form-control` is the placeholder selector that is used to style all form controls. +`.form-control` is the class that is used to style all form controls. `.form-control:not([type='radio'], [type='checkbox'])` is the selector that is used to style form controls based on the input like color, date, text, number, etc. diff --git a/src/stories/Components/Tag/Tag.mdx b/src/stories/Components/Tag/Tag.mdx index 307913bf..449b5dad 100644 --- a/src/stories/Components/Tag/Tag.mdx +++ b/src/stories/Components/Tag/Tag.mdx @@ -88,7 +88,7 @@ Tag can be used as a standalone component, however, it does have a few dependenc The tag classes are structured using the [BEM methodology](https://getbem.com/naming). -This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all tag behavior by overriding the `.tag` placeholder selector and setting any properties: +This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all tag behavior by overriding the `.tag` class and setting any properties: ```css .tag { diff --git a/tools/templates/component/??name??(pascalCase).mdx b/tools/templates/component/??name??(pascalCase).mdx index 89c771b6..44eb3237 100644 --- a/tools/templates/component/??name??(pascalCase).mdx +++ b/tools/templates/component/??name??(pascalCase).mdx @@ -74,7 +74,7 @@ Here are the variables that can be customized. The ??name??(lowerCase) classes are structured using the [BEM methodology](https://getbem.com/naming). -This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all ??name??(lowerCase) behavior by overriding the `.??name??(lowerCase)` placeholder selector and setting any properties: +This allows us to define core styles on a main [block](https://getbem.com/naming/#block) class, and use [modifiers](https://getbem.com/naming/#modifier) to encapsulate variant styles. You can modify all ??name??(lowerCase) behavior by overriding the `.??name??(lowerCase)` class and setting any properties: ```css .??name??(lowerCase) { @@ -103,6 +103,7 @@ Your application may need a variation. To add one, just follow this template. No ```css .??name??(lowerCase)--{name} { - @extend %??name??(lowerCase)-global; + background-color: + color: } ``` From 68295fb0178c49ad71e24fe60f249c63595380cc Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Sun, 2 Nov 2025 19:06:42 -0500 Subject: [PATCH 08/13] Add distinction comments to button group and segmented control --- src/stories/Components/ButtonGroup/ButtonGroup.mdx | 2 ++ src/stories/Components/SegmentedControl/SegmentedControl.mdx | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/stories/Components/ButtonGroup/ButtonGroup.mdx b/src/stories/Components/ButtonGroup/ButtonGroup.mdx index 73bdc33d..361484f6 100644 --- a/src/stories/Components/ButtonGroup/ButtonGroup.mdx +++ b/src/stories/Components/ButtonGroup/ButtonGroup.mdx @@ -14,6 +14,8 @@ import { createSourceCodeLink } from '../../helpers/sourceCodeLink.js' `.btn-group` is a class that can be added on a container around a collection of buttons. It provides grouping styles for any button conbination and variation that exists in the [Button Component](?path=/docs/navigation-components-button--docs) +Button Group is similar to the Segmented Control component, however it has a different semantic purpose. Button Group is intended to be used for grouping related actions or navigational buttons where Segmented Control is intended to be used for form option selection and submission. See [Segmented Control](?path=/docs/content-components-segmented-control--docs) for details on its usage. + ## Playground diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.mdx b/src/stories/Components/SegmentedControl/SegmentedControl.mdx index c6bfb5c7..007fd14d 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.mdx +++ b/src/stories/Components/SegmentedControl/SegmentedControl.mdx @@ -6,7 +6,7 @@ import { createAlert } from '../Alert/Alert.js' -{/* TODO: Add generator for SimpleForm and finish documentation */} +{/* TODO: Add generator for SimpleForm */} # Segmented Control @@ -18,6 +18,8 @@ import { createAlert } from '../Alert/Alert.js' Segmented Control classes can be used to create a stylized radio select group. +Segmented Control component is similar to the Button Group component, however it has a different semantic purpose. Segmented Control is intended to be used for form option selection and submission where Button Group is intended to be used for grouping related actions or navigational buttons. See [Button Group](?path=/docs/content-components-buttongroup--docs) for details on its usage. + ## Note on Implementation This is just a styling pattern that builds on standard radio inputs and labels. Your project may need some tooling to generate this easily. From 033d3ca95e8a98ad78f6e1315cf4e8715fa18a57 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Sun, 2 Nov 2025 19:12:32 -0500 Subject: [PATCH 09/13] Fix documentation links between components --- src/stories/Components/Avatar/Avatar.js | 2 +- src/stories/Components/Badge/Badge.mdx | 2 +- src/stories/Components/Breadcrumbs/Breadcrumbs.mdx | 2 +- src/stories/Components/ButtonGroup/ButtonGroup.mdx | 4 ++-- src/stories/Components/Navbar/Navbar.mdx | 2 +- src/stories/Components/Pagination/Pagination.mdx | 4 ++-- .../Components/SegmentedControl/SegmentedControl.mdx | 4 ++-- src/stories/Components/Sidebar/Sidebar.mdx | 2 +- src/stories/Components/Tab/Tab.js | 2 +- src/stories/Components/Table/Table.mdx | 2 +- src/stories/Components/Tag/Tag.mdx | 2 +- src/stories/Components/Tooltip/Tooltip.mdx | 2 +- src/stories/Overview/Addons.mdx | 2 +- src/stories/Recipes/Layout/Layout.mdx | 6 +++--- src/stories/Tokens/Shadow.mdx | 2 +- 15 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/stories/Components/Avatar/Avatar.js b/src/stories/Components/Avatar/Avatar.js index fb075309..b47e0267 100644 --- a/src/stories/Components/Avatar/Avatar.js +++ b/src/stories/Components/Avatar/Avatar.js @@ -6,7 +6,7 @@ export const createAvatar = ({ }) => { const element = document.createElement(useLink ? 'a' : 'div') - element.href = '/?path=/docs/content-components-avatar--docs' + element.href = '/?path=/docs/components-avatar--docs' element.className = `avatar avatar--${size}` const image = document.createElement('img') diff --git a/src/stories/Components/Badge/Badge.mdx b/src/stories/Components/Badge/Badge.mdx index 91d07268..040eb557 100644 --- a/src/stories/Components/Badge/Badge.mdx +++ b/src/stories/Components/Badge/Badge.mdx @@ -13,7 +13,7 @@ import { createSourceCodeLink } from '../../helpers/sourceCodeLink.js' }} >
-The Badge component is similar to the Tag component, however it has a different semantic purpose. Badge is intended to be used for notification and information where Tag is intended to be used for interaction and input. See [Tag](?path=/docs/content-components-tag--docs) for details on its usage. +The Badge component is similar to the Tag component, however it has a different semantic purpose. Badge is intended to be used for notification and information where Tag is intended to be used for interaction and input. See [Tag](?path=/docs/components-tag--docs) for details on its usage. ## Playground diff --git a/src/stories/Components/Breadcrumbs/Breadcrumbs.mdx b/src/stories/Components/Breadcrumbs/Breadcrumbs.mdx index 5be96931..3b62a2ed 100644 --- a/src/stories/Components/Breadcrumbs/Breadcrumbs.mdx +++ b/src/stories/Components/Breadcrumbs/Breadcrumbs.mdx @@ -52,7 +52,7 @@ Breadcrumbs can be used as a standalone component, however, it does have a few d ### Separator -`.breadcrumbs__separator` is used to separate the links in the breadcrumbs. It is a div that anything can be put within, however typically would be used with an [Icon](?path=/docs/visual-components-icon--docs). +`.breadcrumbs__separator` is used to separate the links in the breadcrumbs. It is a div that anything can be put within, however typically would be used with an [Icon](?path=/docs/components-icon--docs). diff --git a/src/stories/Components/ButtonGroup/ButtonGroup.mdx b/src/stories/Components/ButtonGroup/ButtonGroup.mdx index 361484f6..05617c3d 100644 --- a/src/stories/Components/ButtonGroup/ButtonGroup.mdx +++ b/src/stories/Components/ButtonGroup/ButtonGroup.mdx @@ -12,9 +12,9 @@ import { createSourceCodeLink } from '../../helpers/sourceCodeLink.js' }} > -`.btn-group` is a class that can be added on a container around a collection of buttons. It provides grouping styles for any button conbination and variation that exists in the [Button Component](?path=/docs/navigation-components-button--docs) +`.btn-group` is a class that can be added on a container around a collection of buttons. It provides grouping styles for any button conbination and variation that exists in the [Button Component](?path=/docs/components-button--docs) -Button Group is similar to the Segmented Control component, however it has a different semantic purpose. Button Group is intended to be used for grouping related actions or navigational buttons where Segmented Control is intended to be used for form option selection and submission. See [Segmented Control](?path=/docs/content-components-segmented-control--docs) for details on its usage. +Button Group is similar to the Segmented Control component, however it has a different semantic purpose. Button Group is intended to be used for grouping related actions or navigational buttons where Segmented Control is intended to be used for form option selection and submission. See [Segmented Control](?path=/docs/components-segmented-control--docs) for details on its usage. ## Playground diff --git a/src/stories/Components/Navbar/Navbar.mdx b/src/stories/Components/Navbar/Navbar.mdx index b3b679fc..cde157c9 100644 --- a/src/stories/Components/Navbar/Navbar.mdx +++ b/src/stories/Components/Navbar/Navbar.mdx @@ -20,7 +20,7 @@ For instructions on how to integrate a navbar into your applications layout, see `.navbar` is the main component that everything is contained within. -Any [Button](?path=/docs/navigation-components-button--docs#default) style can be used for the links. +Any [Button](?path=/docs/components-button--docs#default) style can be used for the links. ## Playground diff --git a/src/stories/Components/Pagination/Pagination.mdx b/src/stories/Components/Pagination/Pagination.mdx index 2ef17174..fa9a75a1 100644 --- a/src/stories/Components/Pagination/Pagination.mdx +++ b/src/stories/Components/Pagination/Pagination.mdx @@ -16,7 +16,7 @@ import { createAlert } from '../Alert/Alert.js' Pagination is used to navigate through a series of pages, typically when dealing with tabular data. A few classes are used in combination with the button component to achieve this. -An example of using this component with the Table component can be found in [Table With Pagination](?path=/docs/content-components-table--docs#with-pagination). +An example of using this component with the Table component can be found in [Table With Pagination](?path=/docs/components-table--docs#with-pagination). ## Note on Implementation @@ -51,7 +51,7 @@ Pagination can be used as a standalone component, however, it does have a few de ### Default -`.pagination` Is the main class. It can be placed on a `nav` element and wraps a collection of [buttons](?path=/docs/navigation-components-button--docs) to create a pagination component. +`.pagination` Is the main class. It can be placed on a `nav` element and wraps a collection of [buttons](?path=/docs/components-button--docs) to create a pagination component. The buttons within can use any of the button classes, but form a default look, use the `.btn .btn--no-border .btn--small` classes. diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.mdx b/src/stories/Components/SegmentedControl/SegmentedControl.mdx index 007fd14d..cd712e9f 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.mdx +++ b/src/stories/Components/SegmentedControl/SegmentedControl.mdx @@ -18,7 +18,7 @@ import { createAlert } from '../Alert/Alert.js' Segmented Control classes can be used to create a stylized radio select group. -Segmented Control component is similar to the Button Group component, however it has a different semantic purpose. Segmented Control is intended to be used for form option selection and submission where Button Group is intended to be used for grouping related actions or navigational buttons. See [Button Group](?path=/docs/content-components-buttongroup--docs) for details on its usage. +Segmented Control component is similar to the Button Group component, however it has a different semantic purpose. Segmented Control is intended to be used for form option selection and submission where Button Group is intended to be used for grouping related actions or navigational buttons. See [Button Group](?path=/docs/components-buttongroup--docs) for details on its usage. ## Note on Implementation @@ -64,7 +64,7 @@ SegmentedControl can be used as a standalone component, however, it does have a `.segmented-control__label` can be used on the radio labels. -The [Icon](?path=/docs/content-components-icon--docs) component can be used within the label as a prefix or suffix and will follow the sizing appropriately. +The [Icon](?path=/docs/components-icon--docs) component can be used within the label as a prefix or suffix and will follow the sizing appropriately. diff --git a/src/stories/Components/Sidebar/Sidebar.mdx b/src/stories/Components/Sidebar/Sidebar.mdx index 3d5ea9d9..06c59726 100644 --- a/src/stories/Components/Sidebar/Sidebar.mdx +++ b/src/stories/Components/Sidebar/Sidebar.mdx @@ -25,7 +25,7 @@ For instructions on how to integrate a sidebar into your applications layout, se ``` -Any [Button](?path=/docs/navigation-components-button--docs#default) style can be used for the links. +Any [Button](?path=/docs/components-button--docs#default) style can be used for the links. - Drawer will use the normal button style, but left aligned - Compact will use the `.icon-with-label` style diff --git a/src/stories/Components/Tab/Tab.js b/src/stories/Components/Tab/Tab.js index 4d228aa9..9323dc9e 100644 --- a/src/stories/Components/Tab/Tab.js +++ b/src/stories/Components/Tab/Tab.js @@ -4,7 +4,7 @@ export const createTab = ({ size = 'large', activeTab = 'USA', disabledTab = 'Ca const createTabItem = (item) => { const link = document.createElement('a') - link.href = '/?path=/docs/navigation-components-tab--docs' + link.href = '/?path=/docs/components-tab--docs' link.className = [ 'tab', diff --git a/src/stories/Components/Table/Table.mdx b/src/stories/Components/Table/Table.mdx index bff9442b..e868e47f 100644 --- a/src/stories/Components/Table/Table.mdx +++ b/src/stories/Components/Table/Table.mdx @@ -99,7 +99,7 @@ These are best used in conjunction with a wrapping container fixed table height, ### With Pagination -The [Pagination](?path=/docs/navigation-components-pagination--docs) component can be used with the table to provide a way to navigate through a large dataset. +The [Pagination](?path=/docs/components-pagination--docs) component can be used with the table to provide a way to navigate through a large dataset. Here is an example of using it in the table footer. diff --git a/src/stories/Components/Tag/Tag.mdx b/src/stories/Components/Tag/Tag.mdx index 449b5dad..17061001 100644 --- a/src/stories/Components/Tag/Tag.mdx +++ b/src/stories/Components/Tag/Tag.mdx @@ -13,7 +13,7 @@ import { createAlert } from '../Alert/Alert.js' }} > -The tag component can be applied to an element with a button within it. The Tag component is similar to the Badge component, however it has a different semantic purpose. Tag is intended to be used for interaction and input where Badge is intended to be used for Notification and Information. See [Badge](?path=/docs/content-components-badge--docs) for details on its usage. +The tag component can be applied to an element with a button within it. The Tag component is similar to the Badge component, however it has a different semantic purpose. Tag is intended to be used for interaction and input where Badge is intended to be used for Notification and Information. See [Badge](?path=/docs/components-badge--docs) for details on its usage. The tag will typically have a button within it. The button can be used to remove the tag from the UI. For Example, managing catgories or metadata tags on a data record. diff --git a/src/stories/Components/Tooltip/Tooltip.mdx b/src/stories/Components/Tooltip/Tooltip.mdx index cf67e183..a8cf5950 100644 --- a/src/stories/Components/Tooltip/Tooltip.mdx +++ b/src/stories/Components/Tooltip/Tooltip.mdx @@ -48,7 +48,7 @@ Tooltip can be used as a standalone component, however, it does have a few depen ## Note on usage with Button -There are cases when you might want to put a tooltip on a disabled [Button](?path=/docs/navigation-components-button--docs). Unfortunately due to the implementation of button which prioritizes simpler and easier to customize code, the hover is blocked which causes the tooltip to not show up. +There are cases when you might want to put a tooltip on a disabled [Button](?path=/docs/components-button--docs). Unfortunately due to the implementation of button which prioritizes simpler and easier to customize code, the hover is blocked which causes the tooltip to not show up. The workaround for this is to wrap your disabled button in a span and put the tooltip on the span instead. diff --git a/src/stories/Overview/Addons.mdx b/src/stories/Overview/Addons.mdx index 16b2fd2e..af66741f 100644 --- a/src/stories/Overview/Addons.mdx +++ b/src/stories/Overview/Addons.mdx @@ -35,7 +35,7 @@ Optics supports alternative icon libraries. It currently supports These can be imported alongside the base design system to provide additional icon options. -For more information on how to use these icons, see the [Icon Component](?path=/docs/visual-components-icon--docs). +For more information on how to use these icons, see the [Icon Component](?path=/docs/components-icon--docs). ```css @import '@rolemodel/optics'; diff --git a/src/stories/Recipes/Layout/Layout.mdx b/src/stories/Recipes/Layout/Layout.mdx index 393a4606..e3f5e09c 100644 --- a/src/stories/Recipes/Layout/Layout.mdx +++ b/src/stories/Recipes/Layout/Layout.mdx @@ -99,7 +99,7 @@ If you need a fullscreen spinner, use a layout like this: ## With Sidebar -For instructions on the sidebar itself, see [Sidebar Component](?path=/docs/navigation-components-sidebar--default-drawer) +For instructions on the sidebar itself, see [Sidebar Component](?path=/docs/components-sidebar--default-drawer) A layout with a sidebar looks like the following: @@ -136,7 +136,7 @@ A layout with a sidebar looks like the following: ## With Navbar -For instructions on the navbar itself, see [Navbar Component](?path=/docs/navigation-components-navbar--default-navbar) +For instructions on the navbar itself, see [Navbar Component](?path=/docs/components-navbar--default-navbar) A layout with a navbar looks like the following: @@ -165,7 +165,7 @@ A layout with a navbar looks like the following: ## Sidebar with Navbar and Side Panel -For instructions on the side panel itself, see [Side Panel Component](?path=/docs/content-components-sidepanel--docs) +For instructions on the side panel itself, see [Side Panel Component](?path=/docs/components-sidepanel--docs) A layout with a side panel looks like the following: diff --git a/src/stories/Tokens/Shadow.mdx b/src/stories/Tokens/Shadow.mdx index be0cf8f6..a2760c6c 100644 --- a/src/stories/Tokens/Shadow.mdx +++ b/src/stories/Tokens/Shadow.mdx @@ -12,7 +12,7 @@ import { createSourceCodeLink } from '../helpers/sourceCodeLink.js' }} > -Shadow tokens can be used to create an elevation effect on any element. There are also [Card classes](?path=/docs/content-components-card--docs#shadow) to create an elevated card effect. +Shadow tokens can be used to create an elevation effect on any element. There are also [Card classes](?path=/docs/components-card--docs#shadow) to create an elevated card effect. ## Usage From e6b9e12b249385fb9d47a2710e5c3b19fa57c108 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Wed, 5 Nov 2025 10:01:56 -0500 Subject: [PATCH 10/13] Add full width option to segmented control --- src/components/segmented-control.css | 7 ++++++- .../Components/SegmentedControl/SegmentedControl.js | 7 ++++++- .../SegmentedControl/SegmentedControl.mdx | 6 ++++++ .../SegmentedControl/SegmentedControl.stories.js | 13 +++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/components/segmented-control.css b/src/components/segmented-control.css index cc1039ad..751caad7 100644 --- a/src/components/segmented-control.css +++ b/src/components/segmented-control.css @@ -47,6 +47,10 @@ gap: var(--op-space-2x-small); grid-auto-flow: column; + &.segmented-control--full-width { + width: 100%; + } + .icon { color: var(--__op-segmented-control-color-icon); } @@ -79,10 +83,11 @@ .segmented-control__label { display: inline-flex; + align-items: center; + justify-content: center; border-radius: var(--op-radius-small); gap: var(--__op-segmented-control-label-gap); padding-inline: var(--__op-segmented-control-label-padding); - place-items: center; white-space: nowrap; &:hover { diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.js b/src/stories/Components/SegmentedControl/SegmentedControl.js index 8ea7cbe1..3cc6c266 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.js +++ b/src/stories/Components/SegmentedControl/SegmentedControl.js @@ -36,6 +36,7 @@ const createOptionLabel = (index, showPrefixIcon, showSuffixIcon) => { export const createSegmentedControl = ({ size = 'large', + fullWidth = false, showPrefixIcon = false, showSuffixIcon = false, options = 3, @@ -43,7 +44,11 @@ export const createSegmentedControl = ({ const element = document.createElement('div') element.role = 'radiogroup' - element.className = ['segmented-control', size === 'large' ? '' : `segmented-control--${size}`] + element.className = [ + 'segmented-control', + size === 'large' ? '' : `segmented-control--${size}`, + fullWidth ? 'segmented-control--full-width' : '', + ] .filter(Boolean) .join(' ') diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.mdx b/src/stories/Components/SegmentedControl/SegmentedControl.mdx index cd712e9f..60e0fbd9 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.mdx +++ b/src/stories/Components/SegmentedControl/SegmentedControl.mdx @@ -74,6 +74,12 @@ The [Icon](?path=/docs/components-icon--docs) component can be used within the l +### Full Width + +`.segmented-control--full-width` can be used to make the segmented control take up the full width of its container. + + + ## SegmentedControl API Styles are built on css variables scoped to the segmented control. diff --git a/src/stories/Components/SegmentedControl/SegmentedControl.stories.js b/src/stories/Components/SegmentedControl/SegmentedControl.stories.js index 7194e483..ee61776f 100644 --- a/src/stories/Components/SegmentedControl/SegmentedControl.stories.js +++ b/src/stories/Components/SegmentedControl/SegmentedControl.stories.js @@ -11,6 +11,9 @@ export default { options: ['small', 'medium', 'large'], }, options: { control: 'number' }, + fullWidth: { + control: 'boolean', + }, showPrefixIcon: { control: 'boolean', description: 'This is not a class. It just provides an example of using icons within the options', @@ -20,6 +23,9 @@ export default { description: 'This is not a class. It just provides an example of using icons within the options', }, }, + parameters: { + layout: 'padded', + }, } export const Default = { @@ -38,6 +44,13 @@ export const Size = { }, } +export const FullWidth = { + args: { + label: 'Full Width', + fullWidth: true, + }, +} + export const WithIcons = { args: { showSuffixIcon: true, From 90cea25a1fc74eaa322e766025a87df071e4bdc6 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Wed, 5 Nov 2025 10:02:59 -0500 Subject: [PATCH 11/13] Ensure segmented control lays out properly in a form group --- src/components/form.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/form.css b/src/components/form.css index a5b12508..9c941029 100644 --- a/src/components/form.css +++ b/src/components/form.css @@ -259,7 +259,8 @@ textarea.form-control:not([type='radio'], [type='checkbox']) { .form-label, .form-error, .form-hint, - .form-control:not([type='radio'], [type='checkbox']) { + .form-control:not([type='radio'], [type='checkbox']), + .segmented-control { grid-column: 1 / 3; } /* stylelint-enable no-descending-specificity */ From a265b3ad62ab323c9a3cdba6831b85965d53f6bb Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Wed, 5 Nov 2025 10:05:22 -0500 Subject: [PATCH 12/13] Bump version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7fdca621..8908666d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rolemodel/optics", - "version": "2.1.5", + "version": "2.2.0", "packageManager": "yarn@4.8.1", "description": "Optics is a css package that provides base styles and components that can be integrated and customized in a variety of projects.", "main": "dist/css/optics.css", From b1c85efa13dedbc3a93dd487963476c87816e508 Mon Sep 17 00:00:00 2001 From: Jeremy Walton Date: Wed, 5 Nov 2025 13:21:13 -0500 Subject: [PATCH 13/13] Update switch documentation to match segmented controls newer descreiption --- src/stories/Components/Switch/Switch.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stories/Components/Switch/Switch.mdx b/src/stories/Components/Switch/Switch.mdx index a2cc33a5..0417fe65 100644 --- a/src/stories/Components/Switch/Switch.mdx +++ b/src/stories/Components/Switch/Switch.mdx @@ -17,9 +17,9 @@ Switch classes can be used to create a stylized checkbox or boolean input. ## Note on Implementation -This is just a styling pattern and does not implement the form submission functionality. That is up to the projects needs. +This is just a styling pattern that builds on standard checkbox inputs. Your project may need some tooling to generate this easily. -A commonly used tool for Ruby on Rails projects is [SimpleForm](https://github.com/heartcombo/simple_form). It allows you to build forms with premade inputs and allows you to make custom input types. +A commonly used tool for Ruby on Rails projects is [SimpleForm](https://github.com/heartcombo/simple_form). It allows you to build forms with pre-made inputs and allows you to make custom input types. [RoleModel Rails SimpleForm Generator](https://github.com/RoleModel/rolemodel_rails/tree/master/lib/generators/rolemodel/simple_form) provides a generator to install a custom switch input that can be used with SimpleForm with Optics classes applied.