From c7a1228bb7a3044f1062c26865f744c9d91af5a0 Mon Sep 17 00:00:00 2001 From: Kevin Chang Date: Tue, 10 Sep 2024 09:30:03 -0700 Subject: [PATCH 1/4] feat(select): add help-content slot to react component --- .../stylesheets/components/_form_select.scss | 14 ++++ packages/sage-react/lib/Select/Select.jsx | 11 ++- .../sage-react/lib/Select/Select.story.jsx | 72 ++++++++++++++++++- 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/sage-assets/lib/stylesheets/components/_form_select.scss b/packages/sage-assets/lib/stylesheets/components/_form_select.scss index 40723bf411..08757a5414 100644 --- a/packages/sage-assets/lib/stylesheets/components/_form_select.scss +++ b/packages/sage-assets/lib/stylesheets/components/_form_select.scss @@ -36,6 +36,14 @@ $-select-arrow-position-inverse-with-message: calc(100% - #{$-select-height + $- grid-template-rows: min-content min-content min-content; /* needed to resolve Safari 14 layout issue */ } +.sage-select--help-content { + grid-template-areas: + "label helpcontent helpcontent" + "field field field" + "message message message"; + grid-template-columns: 1fr auto minmax(sage-spacing(lg), min-content); +} + .sage-select__label { @include sage-form-field-label; @@ -64,6 +72,12 @@ $-select-arrow-position-inverse-with-message: calc(100% - #{$-select-height + $- transition: 0.2s color ease; } +.sage-select__help-content { + display: inline-flex; + grid-area: helpcontent; + margin-left: sage-spacing(xs); +} + .sage-select__field { @include sage-form-field(); @include sage-focus-ring; diff --git a/packages/sage-react/lib/Select/Select.jsx b/packages/sage-react/lib/Select/Select.jsx index 57ce236f5d..c65a0b6b22 100644 --- a/packages/sage-react/lib/Select/Select.jsx +++ b/packages/sage-react/lib/Select/Select.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import { SageTokens } from '../configs'; +import { SageClassnames, SageTokens } from '../configs'; export const Select = ({ className, @@ -10,6 +10,7 @@ export const Select = ({ id, includeLabelInOptions, label, + helpContent, message, onChange, options, @@ -24,6 +25,7 @@ export const Select = ({ { 'sage-form-field--error': hasError, 'sage-select--value-selected': value, + 'sage-select--help-content': helpContent, } ); @@ -88,6 +90,11 @@ export const Select = ({ {label && ( )} + {helpContent && ( +
+ {helpContent} +
+ )} {message && (
{message}
@@ -101,6 +108,7 @@ Select.defaultProps = { className: null, disabled: false, hasError: false, + helpContent: null, includeLabelInOptions: false, label: null, message: null, @@ -115,6 +123,7 @@ Select.propTypes = { className: PropTypes.string, disabled: PropTypes.bool, hasError: PropTypes.bool, + helpContent: PropTypes.node, id: PropTypes.string.isRequired, includeLabelInOptions: PropTypes.bool, label: PropTypes.string, diff --git a/packages/sage-react/lib/Select/Select.story.jsx b/packages/sage-react/lib/Select/Select.story.jsx index 9f293e7c23..2f117cdd60 100644 --- a/packages/sage-react/lib/Select/Select.story.jsx +++ b/packages/sage-react/lib/Select/Select.story.jsx @@ -1,5 +1,8 @@ import React, { useState } from 'react'; import { Select } from './Select'; +import { Link } from '../Link'; +import { Popover } from '../Popover'; +import { SageClassnames } from '../configs'; export default { title: 'Sage/Select', @@ -12,7 +15,7 @@ export default { }, }, }, - decorators: [(Story) =>
{Story()}
], + decorators: [(Story) =>
{Story()}
], args: { label: 'Select', id: 'field-1', @@ -98,6 +101,71 @@ SelectWithOptionDisabled.args = { placeholder: 'Pick an option:' }; +export const SelectWithHelpContentLink = (args) => { + const [value, updateValue] = useState(args.value); + return ( + updateValue(evt.target.value)} + /> + ); +}; + +SelectWithHelpContentPopover.args = { + id: 'field-6', + label: 'Select fruit:', + options: [ + 'Apple', + 'Banana', + 'Orange', + 'Peach', + 'Pineapple', + ], + helpContent: ( + +

+ Incredibly helpful text goes here +

+
+ ), + placeholder: 'Select fruit:' +}; + export const SelectWithOptgroups = (args) => { const [value, updateValue] = useState(args.value); return ( @@ -110,7 +178,7 @@ export const SelectWithOptgroups = (args) => { }; SelectWithOptgroups.args = { - id: 'field-3', + id: 'field-7', label: 'Choose a sport...', value: 'nascar', options: [ From c76e3d4d94466f6d6b1cf4b9cbf09db9d0dc0e4a Mon Sep 17 00:00:00 2001 From: Kevin Chang Date: Tue, 10 Sep 2024 10:23:28 -0700 Subject: [PATCH 2/4] feat(select): adds props and documentation for rails component help content --- .../components/form_select/_preview.html.erb | 39 +++++++++++++++++++ .../components/form_select/_props.html.erb | 6 +++ .../app/sage_components/sage_form_select.rb | 1 + .../_sage_form_select.html.erb | 6 +++ 4 files changed, 52 insertions(+) diff --git a/docs/app/views/examples/components/form_select/_preview.html.erb b/docs/app/views/examples/components/form_select/_preview.html.erb index 6398663ad2..0ca69cd008 100644 --- a/docs/app/views/examples/components/form_select/_preview.html.erb +++ b/docs/app/views/examples/components/form_select/_preview.html.erb @@ -59,6 +59,45 @@ <%= sage_component SageDivider, {} %> +

Select with Message and Help Content

+

The Select component can display the "Help content" area to provide inline context alongside the label. This area allows text or other components, and may be useful when the Message area is occupied.

+ +<% sample_help_content = sage_component SageLink, { + url: "https://help.kajabi.com", + label: "External link", + external: true, + launch: true, + help_link: false, + show_label: true, + style: "secondary", + } %> + +<%= sage_component SageFormSelect, { + name: "Default Currency", + select_options: [ + { + text: "USD - United States Dollar", + value: "USD", + }, + { + text: "AED - United Arab Emirates Dirham", + value: "AED", + }, + { + text: "AFN - Afghan Afghani", + value: "AFN", + }, + { + text: "ALL - Albanian Lek", + value: "ALL", + }, + ], + message: "The default currency will be used for formatting and calculation purposes.", + help_content: sample_help_content, +} %> + +<%= sage_component SageDivider, {} %> +

Error State

The Select component can indicate an error state.

diff --git a/docs/app/views/examples/components/form_select/_props.html.erb b/docs/app/views/examples/components/form_select/_props.html.erb index 04c7d21794..238fd73aed 100644 --- a/docs/app/views/examples/components/form_select/_props.html.erb +++ b/docs/app/views/examples/components/form_select/_props.html.erb @@ -10,6 +10,12 @@ <%= md('Boolean') %> <%= md('`false`') %> + + <%= md('`help_content`') %> + <%= md('Sets the content for the "help content" area adjacent to the select\'s label') %> + <%= md('String') %> + <%= md('`nil`') %> + <%= md('`message`') %> <%= md('Displays the message text for the component.') %> diff --git a/docs/lib/sage_rails/app/sage_components/sage_form_select.rb b/docs/lib/sage_rails/app/sage_components/sage_form_select.rb index a7ebef08bb..f526ecb0dd 100644 --- a/docs/lib/sage_rails/app/sage_components/sage_form_select.rb +++ b/docs/lib/sage_rails/app/sage_components/sage_form_select.rb @@ -2,6 +2,7 @@ class SageFormSelect < SageComponent set_attribute_schema({ disabled: [:optional, NilClass, TrueClass], has_error: [:optional, NilClass, TrueClass], + help_content: [:optional, NilClass, String], id: [:optional, NilClass, String], label: [:optional, NilClass, String], message: [:optional, NilClass, String], diff --git a/docs/lib/sage_rails/app/views/sage_components/_sage_form_select.html.erb b/docs/lib/sage_rails/app/views/sage_components/_sage_form_select.html.erb index ffb87636dc..fd321c5ffc 100644 --- a/docs/lib/sage_rails/app/views/sage_components/_sage_form_select.html.erb +++ b/docs/lib/sage_rails/app/views/sage_components/_sage_form_select.html.erb @@ -7,6 +7,7 @@
+ <%= "sage-select--help-content" if component.help_content %> <%= component.generated_css_classes %>" data-js-select="true" <%= component.generated_html_attributes.html_safe %> @@ -48,6 +49,11 @@ <% end %> + <% if component.help_content.present? %> +
+ <%= component.help_content %> +
+ <% end %>