-
Notifications
You must be signed in to change notification settings - Fork 518
feat: allow any operator in segment top rule #7427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Zaimwa9
wants to merge
12
commits into
main
Choose a base branch
from
feat/allow-any-operator-in-segment-top-rule
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
cacb97c
feat: implemented toggle any and all rules with correct text diff
Zaimwa9 8f2f704
feat: show error message when top rules have different types
Zaimwa9 83c0d83
feat: render top-level any rules in segment diff
Zaimwa9 aff9247
feat: added segment rules any type e2e tests
Zaimwa9 da5bb98
feat: create feature in segment 4 test
Zaimwa9 c5a692c
deps: bump engine to 10.1.0
Zaimwa9 c7c04e7
Merge branch 'deps/bump-flag-engine-version' of github.com:Flagsmith/…
Zaimwa9 2faa840
Merge branch 'main' of github.com:Flagsmith/flagsmith into feat/allow…
Zaimwa9 984ef89
feat: use semantic tokens in pill
Zaimwa9 4b8ece9
feat:gate top-level rule type click on segment_any_rule_type flag
Zaimwa9 2ad9089
feat: add keyboard nav and focus-visible to InlinePillToggle
Zaimwa9 e821a39
fix: preserve NONE sub-rules when toggling top-level rule type
Zaimwa9 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
98 changes: 98 additions & 0 deletions
98
frontend/documentation/components/InlinePillToggle.stories.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import React, { useState } from 'react' | ||
| import type { Meta, StoryObj } from 'storybook' | ||
|
|
||
| import InlinePillToggle from 'components/base/forms/InlinePillToggle' | ||
|
|
||
| const meta: Meta = { | ||
| parameters: { | ||
| docs: { | ||
| description: { | ||
| component: | ||
| 'A compact inline segmented control for toggling between two or more options. Available in small, medium, and large sizes.', | ||
| }, | ||
| }, | ||
| layout: 'padded', | ||
| }, | ||
| title: 'Components/Forms/InlinePillToggle', | ||
| } | ||
| export default meta | ||
|
|
||
| type Story = StoryObj | ||
|
|
||
| const options = [ | ||
| { label: 'ALL', value: 'ALL' }, | ||
| { label: 'ANY', value: 'ANY' }, | ||
| ] | ||
|
|
||
| function SmallExample() { | ||
| const [value, setValue] = useState('ALL') | ||
| return ( | ||
| <InlinePillToggle | ||
| size='small' | ||
| options={options} | ||
| value={value} | ||
| onChange={setValue} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| function MediumExample() { | ||
| const [value, setValue] = useState('ALL') | ||
| return ( | ||
| <InlinePillToggle | ||
| size='medium' | ||
| options={options} | ||
| value={value} | ||
| onChange={setValue} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| function LargeExample() { | ||
| const [value, setValue] = useState('ALL') | ||
| return ( | ||
| <InlinePillToggle | ||
| size='large' | ||
| options={options} | ||
| value={value} | ||
| onChange={setValue} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| function InlineWithTextExample() { | ||
| const [value, setValue] = useState('ALL') | ||
| return ( | ||
| <span style={{ fontSize: 14, fontWeight: 600 }}> | ||
| Include users when{' '} | ||
| <InlinePillToggle | ||
| size='small' | ||
| options={options} | ||
| value={value} | ||
| onChange={setValue} | ||
| />{' '} | ||
| of the following rules apply: | ||
| </span> | ||
| ) | ||
| } | ||
|
|
||
| function ThreeOptionsExample() { | ||
| const [value, setValue] = useState('day') | ||
| return ( | ||
| <InlinePillToggle | ||
| options={[ | ||
| { label: 'Day', value: 'day' }, | ||
| { label: 'Week', value: 'week' }, | ||
| { label: 'Month', value: 'month' }, | ||
| ]} | ||
| value={value} | ||
| onChange={setValue} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| export const Small: Story = { render: () => <SmallExample /> } | ||
| export const Medium: Story = { render: () => <MediumExample /> } | ||
| export const Large: Story = { render: () => <LargeExample /> } | ||
| export const InlineWithText: Story = { render: () => <InlineWithTextExample /> } | ||
| export const ThreeOptions: Story = { render: () => <ThreeOptionsExample /> } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| import React, { useRef } from 'react' | ||
| import cn from 'classnames' | ||
|
|
||
| type InlinePillToggleSize = 'small' | 'medium' | 'large' | ||
|
|
||
| type Option<T extends string> = { | ||
| label: string | ||
| value: T | ||
| } | ||
|
|
||
| type InlinePillToggleProps<T extends string> = { | ||
| options: Option<T>[] | ||
| value: T | ||
| onChange: (value: T) => void | ||
| size?: InlinePillToggleSize | ||
| className?: string | ||
| 'data-test'?: string | ||
| } | ||
|
|
||
| function InlinePillToggle<T extends string>({ | ||
| className, | ||
| 'data-test': dataTest, | ||
| onChange, | ||
| options, | ||
| size = 'medium', | ||
| value, | ||
| }: InlinePillToggleProps<T>) { | ||
| const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]) | ||
|
|
||
| const handleKeyDown = (e: React.KeyboardEvent, index: number) => { | ||
| let next: number | null = null | ||
| if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { | ||
| next = (index + 1) % options.length | ||
| } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { | ||
| next = (index - 1 + options.length) % options.length | ||
| } | ||
| if (next !== null) { | ||
| e.preventDefault() | ||
| onChange(options[next].value) | ||
| buttonRefs.current[next]?.focus() | ||
| } | ||
| } | ||
|
|
||
| return ( | ||
| <div | ||
| className={cn( | ||
| 'inline-pill-toggle', | ||
| `inline-pill-toggle--${size}`, | ||
| className, | ||
| )} | ||
| data-test={dataTest} | ||
| role='radiogroup' | ||
| > | ||
| {options.map((option, index) => { | ||
| const isActive = value === option.value | ||
| return ( | ||
| <button | ||
| key={option.value} | ||
| ref={(el) => { | ||
| buttonRefs.current[index] = el | ||
| }} | ||
| type='button' | ||
| role='radio' | ||
| aria-checked={isActive} | ||
| tabIndex={isActive ? 0 : -1} | ||
| data-test={dataTest ? `${dataTest}-${option.value}` : undefined} | ||
| className={cn('inline-pill-toggle__option', { | ||
| 'inline-pill-toggle__option--active': isActive, | ||
| })} | ||
| onClick={() => onChange(option.value)} | ||
| onKeyDown={(e) => handleKeyDown(e, index)} | ||
| > | ||
| {option.label} | ||
| </button> | ||
| ) | ||
| })} | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export default InlinePillToggle | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.