playbook_ui 9.17.0.pre.decouple.website2 → 9.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -5
  3. data/app/assets/images/clark.jpg +0 -0
  4. data/app/assets/images/full_page_samples.svg +7 -0
  5. data/app/assets/images/giant.jpg +0 -0
  6. data/app/assets/images/github-brands.svg +1 -0
  7. data/app/assets/images/landing-background.svg +36 -0
  8. data/app/assets/images/landing-image.svg +203 -0
  9. data/app/assets/images/pb-caret.svg +1 -0
  10. data/app/assets/images/pb-check.svg +11 -0
  11. data/app/assets/images/pb-logo.svg +28 -0
  12. data/app/assets/images/pb-white-logo.svg +15 -0
  13. data/app/assets/images/pb.logo.svg +28 -0
  14. data/app/pb_kits/playbook/index.js +97 -97
  15. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_header_styles.scss +1 -2
  16. data/app/pb_kits/playbook/pb_date_time/docs/_date_time_default.jsx +2 -1
  17. data/app/pb_kits/playbook/pb_dialog/_dialog.jsx +3 -0
  18. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_default.jsx +2 -0
  19. data/app/pb_kits/playbook/pb_enhanced_element/index.js +1 -2
  20. data/app/pb_kits/playbook/pb_message/_message.jsx +32 -9
  21. data/app/pb_kits/playbook/pb_message/_message_mixins.scss +33 -7
  22. data/app/pb_kits/playbook/pb_message/docs/_message_default.html.erb +18 -16
  23. data/app/pb_kits/playbook/pb_message/docs/_message_default.jsx +6 -16
  24. data/app/pb_kits/playbook/pb_message/docs/_message_timestamp.html.erb +18 -0
  25. data/app/pb_kits/playbook/pb_message/docs/_message_timestamp.jsx +32 -0
  26. data/app/pb_kits/playbook/pb_message/docs/example.yml +6 -4
  27. data/app/pb_kits/playbook/pb_message/docs/index.js +1 -0
  28. data/app/pb_kits/playbook/pb_message/message.html.erb +23 -8
  29. data/app/pb_kits/playbook/pb_message/message.rb +2 -0
  30. data/app/pb_kits/playbook/pb_nav/_vertical_nav.scss +2 -2
  31. data/app/pb_kits/playbook/pb_passphrase/_passphrase.jsx +4 -1
  32. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.jsx +8 -10
  33. data/app/pb_kits/playbook/pb_select/_select.scss +1 -1
  34. data/app/pb_kits/playbook/pb_text_input/_text_input.scss +1 -1
  35. data/app/pb_kits/playbook/pb_textarea/_textarea.scss +3 -3
  36. data/app/pb_kits/playbook/pb_title/_title.scss +1 -1
  37. data/app/pb_kits/playbook/pb_title/_title_mixin.scss +40 -1
  38. data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +16 -14
  39. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_async_createable.jsx +58 -0
  40. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
  41. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
  42. data/app/pb_kits/playbook/react_rails_kits.js +13 -0
  43. data/app/pb_kits/playbook/tokens/_colors.scss +0 -4
  44. data/app/pb_kits/playbook/utilities/_colors.scss +4 -0
  45. data/app/pb_kits/playbook/utilities/accessibility.js +22 -0
  46. data/app/pb_kits/playbook/{playbook-rails.js → vendor.js} +5 -1
  47. data/lib/playbook.rb +15 -1
  48. data/lib/playbook/engine.rb +21 -11
  49. data/lib/playbook/props/nested_props.rb +1 -1
  50. data/lib/playbook/version.rb +2 -2
  51. metadata +138 -20
  52. data/app/pb_kits/playbook/_reset.scss +0 -42
  53. data/app/pb_kits/playbook/playbook-doc.js +0 -195
  54. data/app/pb_kits/playbook/playbook-rails-react-bindings.js +0 -35
  55. data/app/pb_kits/playbook/tokens/_titles.scss +0 -38
@@ -9,6 +9,8 @@ module Playbook
9
9
  prop :label
10
10
  prop :message
11
11
  prop :timestamp
12
+ prop :timestamp_object
13
+ prop :align_timestamp, type: Playbook::Props::Enum, values: %w[left right], default: "right"
12
14
 
13
15
  def classname
14
16
  generate_classname("pb_message_kit", avatar_class)
@@ -3,8 +3,8 @@
3
3
  @import "../tokens/border_radius";
4
4
  @import "../tokens/animation-curves";
5
5
  @import "../tokens/typography";
6
- @import "../tokens/titles";
7
6
  @import "../pb_body/body_mixins";
7
+ @import "../pb_title/title_mixin";
8
8
  @import "./subtle_mixin";
9
9
 
10
10
  $selector: ".pb_nav_list";
@@ -134,7 +134,7 @@ $selector: ".pb_nav_list";
134
134
  border-bottom: 0;
135
135
  }
136
136
  }
137
-
137
+
138
138
  }
139
139
 
140
140
  //Image Wrapper
@@ -74,7 +74,10 @@ const Passphrase = (props: PassphraseProps) => {
74
74
  }
75
75
 
76
76
  const [showPassphrase, setShowPassphrase] = useState(false)
77
- const toggleShowPassphrase = () => setShowPassphrase(!showPassphrase)
77
+ const toggleShowPassphrase = (e) => {
78
+ e.preventDefault()
79
+ setShowPassphrase(!showPassphrase)
80
+ }
78
81
 
79
82
  const classes = classnames(buildCss('pb_passphrase'), globalProps(props), className)
80
83
 
@@ -2,18 +2,11 @@
2
2
 
3
3
  import React, { useEffect, useRef } from 'react'
4
4
  import classnames from 'classnames'
5
- import useFocus from './useFocus'
6
- import { globalProps } from '../utilities/globalProps'
5
+ import useFocus from './useFocus.js'
6
+ import Trix from 'trix'
7
+ import { globalProps } from '../utilities/globalProps.js'
7
8
  import { buildAriaProps, buildDataProps } from '../utilities/props'
8
9
 
9
- try {
10
- const Trix = require('trix')
11
- Trix.config.textAttributes.inlineCode = {
12
- tagName: 'code',
13
- inheritable: true,
14
- }
15
- } catch (_e) { /* do nothing */ }
16
-
17
10
  type RichTextEditorProps = {
18
11
  aria?: object,
19
12
  toolbarBottom?: Boolean,
@@ -53,6 +46,11 @@ const RichTextEditor = (props: RichTextEditorProps) => {
53
46
  const dataProps = buildDataProps(data)
54
47
 
55
48
  useEffect(() => {
49
+ Trix.config.textAttributes.inlineCode = {
50
+ tagName: 'code',
51
+ inheritable: true,
52
+ }
53
+
56
54
  trixRef.current.addEventListener('trix-initialize', (event) => {
57
55
  const element = event.target
58
56
 
@@ -1,6 +1,6 @@
1
1
  @import "../pb_body/body_mixins";
2
2
  @import "../pb_textarea/textarea_mixin";
3
- @import "../tokens/titles";
3
+ @import "../pb_title/title_mixin";
4
4
  @import "../tokens/colors";
5
5
 
6
6
  [class^=pb_select] {
@@ -1,5 +1,5 @@
1
1
  @import "../pb_textarea/textarea_mixin";
2
- @import "../tokens/titles";
2
+ @import "../pb_title/title_mixin";
3
3
  @import "../tokens/colors";
4
4
 
5
5
 
@@ -1,11 +1,11 @@
1
1
  @import "../pb_body/body_mixins";
2
2
  @import "./textarea_mixin";
3
+ @import "../pb_title/title_mixin";
3
4
  @import "../tokens/spacing";
4
- @import "../tokens/titles";
5
5
 
6
6
  [class^=pb_textarea_kit] {
7
7
  margin-bottom: $space_sm;
8
-
8
+
9
9
  [class^=pb_caption_kit] {
10
10
  margin-bottom: $space_xs;
11
11
  display: block;
@@ -28,7 +28,7 @@
28
28
  .pb_text_area_kit:hover {
29
29
  background-color: rgba($focus_input_light,$opacity_5);
30
30
  }
31
-
31
+
32
32
  &.resize_both > textarea {
33
33
  resize: both;
34
34
  overflow: auto;
@@ -1,4 +1,4 @@
1
- @import "../tokens/titles";
1
+ @import "title_mixin";
2
2
  @import "../tokens/colors";
3
3
 
4
4
  [class^=pb_title_kit]{
@@ -1 +1,40 @@
1
- @import "../tokens/titles";
1
+ @import "../tokens/colors";
2
+ @import "../tokens/typography";
3
+ @import "../tokens/line_height";
4
+
5
+ @mixin pb_title(
6
+ $fontSize: $heading_1,
7
+ $fontWeight: $lighter,
8
+ $lineHeight: $lh_tighter
9
+ ){
10
+ font-size: $fontSize;
11
+ letter-spacing: $lspace_tight;
12
+ font-weight: $fontWeight;
13
+ color: $text_lt_default;
14
+ margin: 0;
15
+ line-height: $lineHeight;
16
+ font-family: $font_family_base;
17
+ }
18
+
19
+ @mixin pb_title_1 {
20
+ @include pb_title($heading_1);
21
+ letter-spacing: -0.03em;
22
+ }
23
+
24
+ @mixin pb_title_2 {
25
+ @include pb_title($heading_2, $lighter, 0.96);
26
+ }
27
+
28
+ @mixin pb_title_3 {
29
+ @include pb_title($heading_3);
30
+ }
31
+
32
+ @mixin pb_title_4 {
33
+ @include pb_title($heading_4, $bolder);
34
+ }
35
+
36
+ @mixin pb_title_dark {
37
+ color: $text_dk_default;
38
+ }
39
+
40
+
@@ -4,7 +4,8 @@ import React from 'react'
4
4
  import Select from 'react-select'
5
5
  import AsyncSelect from 'react-select/async'
6
6
  import CreateableSelect from 'react-select/creatable'
7
- import { get, isString, uniqueId } from 'lodash'
7
+ import AsyncCreateableSelect from 'react-select/async-creatable'
8
+ import { get } from 'lodash'
8
9
  import { globalProps } from '../utilities/globalProps.js'
9
10
  import classnames from 'classnames'
10
11
 
@@ -26,24 +27,23 @@ import { noop } from '../utilities/props'
26
27
  * @prop {string} label - the text for the optional typeahead input label
27
28
  */
28
29
 
29
- type TypeaheadProps = {
30
- id?: string,
30
+ type Props = {
31
31
  async?: boolean,
32
32
  createable?: boolean,
33
33
  dark?: boolean,
34
34
  label?: string,
35
- loadOptions?: string,
36
- getOptionLabel?: string | (() => any),
37
- getOptionValue?: string | (() => any),
35
+ loadOptions?: noop | string,
36
+ getOptionLabel?: () => any,
37
+ getOptionValue?: () => any,
38
38
  name?: string,
39
39
  }
40
40
 
41
41
  /**
42
42
  * @constant {React.ReactComponent} Typeahead
43
- * @param {TypeaheadProps} props - props as described at https://react-select.com/props
43
+ * @param {Props} props - props as described at https://react-select.com/props
44
44
  */
45
45
 
46
- const Typeahead = ({ loadOptions = noop, getOptionLabel, id, getOptionValue, createable, async, ...props }: TypeaheadProps) => {
46
+ const Typeahead = (props: Props) => {
47
47
  const selectProps = {
48
48
  cacheOptions: true,
49
49
  components: {
@@ -57,11 +57,8 @@ const Typeahead = ({ loadOptions = noop, getOptionLabel, id, getOptionValue, cre
57
57
  Placeholder,
58
58
  ValueContainer,
59
59
  },
60
- loadOptions: isString(loadOptions) ? get(window, loadOptions) : loadOptions,
61
- getOptionLabel: isString(getOptionLabel) ? get(window, getOptionLabel) : getOptionLabel,
62
- getOptionValue: isString(getOptionValue) ? get(window, getOptionValue) : getOptionValue,
63
60
  defaultOptions: true,
64
- id: id || uniqueId(),
61
+ id: 'react-select-input',
65
62
  inline: false,
66
63
  isClearable: true,
67
64
  isSearchable: true,
@@ -72,9 +69,14 @@ const Typeahead = ({ loadOptions = noop, getOptionLabel, id, getOptionValue, cre
72
69
  ...props,
73
70
  }
74
71
 
75
- const Tag = createable ? CreateableSelect : (async ? AsyncSelect : Select)
72
+ if (typeof(props.loadOptions) === 'string') selectProps.loadOptions = get(window, props.loadOptions)
73
+ if (typeof(props.getOptionLabel) === 'string') selectProps.getOptionLabel = get(window, props.getOptionLabel)
74
+ if (typeof(props.getOptionValue) === 'string') selectProps.getOptionValue = get(window, props.getOptionValue)
76
75
 
77
- const handleOnChange = (_data, { action, option, removedValue }) => {
76
+ let Tag = props.async ? AsyncSelect : Select
77
+ if (props.createable) Tag = props.async ? AsyncCreateableSelect : CreateableSelect
78
+
79
+ const handleOnChange = (data, { action, option, removedValue }) => {
78
80
  if (action === 'select-option') {
79
81
  if (selectProps.onMultiValueClick) selectProps.onMultiValueClick(option)
80
82
  const multiValueClearEvent = new CustomEvent(`pb-typeahead-kit-${selectProps.id}-result-option-select`, { detail: option })
@@ -0,0 +1,58 @@
1
+ // @flow
2
+
3
+ import React from 'react'
4
+ import { Typeahead } from '../..'
5
+
6
+ /**
7
+ *
8
+ * @const filterResults
9
+ * @ignore
10
+ * @returns {[Object]} - a custom mapping of objects, minimally containing
11
+ * `value` and `label` among other possible fields
12
+ * @summary - for doc example purposes only
13
+ */
14
+
15
+ const filterResults = (results) =>
16
+ results.items.map((result) => {
17
+ return {
18
+ label: result.login,
19
+ value: result.id,
20
+ }
21
+ })
22
+
23
+ /**
24
+ *
25
+ * @const promiseOptions
26
+ * @ignore
27
+ * @returns {Promise} - fetch API data results from Typeahead input text
28
+ * @see - https://react-select.com/home#async
29
+ * @summary - for doc example purposes only
30
+ */
31
+
32
+ const promiseOptions = (inputValue) =>
33
+ new Promise((resolve) => {
34
+ if (inputValue) {
35
+ fetch(`https://api.github.com/search/users?q=${inputValue}`)
36
+ .then((response) => response.json())
37
+ .then((results) => {
38
+ resolve(results.items ? filterResults(results) : [])
39
+ })
40
+ } else {
41
+ resolve([])
42
+ }
43
+ })
44
+
45
+ const TypeaheadAsyncCreateable = (props) => {
46
+ return (
47
+ <Typeahead
48
+ async
49
+ createable
50
+ isMulti
51
+ label="Existing or User Created Options"
52
+ loadOptions={promiseOptions}
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ export default TypeaheadAsyncCreateable
@@ -17,3 +17,4 @@ examples:
17
17
  - typeahead_inline: Inline
18
18
  - typeahead_multi_kit: Multi Kit Options
19
19
  - typeahead_createable: Createable
20
+ - typeahead_async_createable: Createable (+ Async Data)
@@ -6,3 +6,4 @@ export { default as TypeaheadWithPillsAsyncCustomOptions } from './_typeahead_wi
6
6
  export { default as TypeaheadInline } from './_typeahead_inline.jsx'
7
7
  export { default as TypeaheadMultiKit } from './_typeahead_multi_kit.jsx'
8
8
  export { default as TypeaheadCreateable } from './_typeahead_createable.jsx'
9
+ export { default as TypeaheadAsyncCreateable } from './_typeahead_async_createable.jsx'
@@ -0,0 +1,13 @@
1
+ // React-Rendered Rails Kit Exports =====
2
+ export { default as BarGraph } from './pb_bar_graph/_bar_graph.jsx'
3
+ export { default as DistributionBar } from './pb_distribution_bar/_distribution_bar.jsx'
4
+ export { default as Legend } from './pb_legend/_legend.jsx'
5
+ export { default as LineGraph } from './pb_line_graph/_line_graph.jsx'
6
+ export { default as Passphrase } from './pb_passphrase/_passphrase.jsx'
7
+ export { default as Typeahead } from './pb_typeahead/_typeahead.jsx'
8
+ export { default as RichTextEditor } from './pb_rich_text_editor/_rich_text_editor.jsx'
9
+ export { default as Dialog } from './pb_dialog/_dialog.jsx'
10
+ export { default as DialogHeader } from './pb_dialog/child_kits/_dialog_header.jsx'
11
+ export { default as DialogBody } from './pb_dialog/child_kits/_dialog_body.jsx'
12
+ export { default as DialogFooter } from './pb_dialog/child_kits/_dialog_footer.jsx'
13
+ export { KitSearch, SnippetToggle, DarkModeToggle } from './docs_components'
@@ -243,10 +243,6 @@ $category_colors: (
243
243
 
244
244
  $transparent: transparent;
245
245
 
246
- @function tint($color, $percentage) {
247
- @return mix($white, $color, $percentage);
248
- }
249
-
250
246
  @mixin gradient($start: $gradient_start, $end: $gradient_end) {
251
247
  background: $start;
252
248
  background: -moz-linear-gradient(-45deg, $start 0%, $end 100%);
@@ -1,3 +1,7 @@
1
+ @function tint($color, $percentage) {
2
+ @return mix($white, $color, $percentage);
3
+ }
4
+
1
5
  @function shade($color, $percentage) {
2
6
  @return mix($charcoal, $color, $percentage);
3
7
  }
@@ -0,0 +1,22 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import axe from 'axe-core'
4
+
5
+ export const runAxe = function(include = '.pb--kit-example', ignore = ['.pb--kit-example :first-child']) {
6
+ axe
7
+ .run({
8
+ include: [include],
9
+ exclude: [ignore],
10
+ })
11
+ .then((results) => {
12
+ if (results.violations.length) {
13
+ console.warn('🚨 [axe-core] Accessibility issues found. See below for a list:')
14
+ console.dir(results.violations)
15
+ } else {
16
+ console.log('[axe-core] Yay! 🎉 No accessibility violations were found!')
17
+ }
18
+ })
19
+ .catch((err) => {
20
+ console.error('Something bad happened:', err.message)
21
+ })
22
+ }
@@ -35,5 +35,9 @@ PbTextarea.start()
35
35
 
36
36
  import 'flatpickr'
37
37
 
38
+ import 'trix'
39
+
38
40
  // React-Rendered Rails Kits =====
39
- import './playbook-rails-react-bindings'
41
+ import WebpackerReact from 'webpacker-react'
42
+ import * as ReactRailsPBKits from './react_rails_kits.js'
43
+ WebpackerReact.setup({ ...ReactRailsPBKits })
data/lib/playbook.rb CHANGED
@@ -1,7 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "sassc-rails"
4
+ require "slim-rails"
5
+ require "webpacker"
6
+ require "webpacker/react"
7
+ require "view_component/engine"
8
+
3
9
  require "playbook/version"
4
- require "playbook/engine"
10
+
5
11
  require "playbook/props"
6
12
  require "playbook/forms"
7
13
  require "playbook/pb_forms_helper"
@@ -10,6 +16,7 @@ require "playbook/pb_doc_helper"
10
16
  require "playbook/kit_base"
11
17
  require "playbook/kit_resolver"
12
18
  require "playbook/markdown"
19
+ require "playbook/engine" if defined?(Rails)
13
20
 
14
21
  module Playbook
15
22
  ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
@@ -19,6 +26,13 @@ module Playbook
19
26
 
20
27
  module_function
21
28
 
29
+ def webpacker
30
+ @webpacker ||= ::Webpacker::Instance.new(
31
+ root_path: ROOT_PATH,
32
+ config_path: ROOT_PATH.join("config/webpacker.yml")
33
+ )
34
+ end
35
+
22
36
  def kit_path(kit, *args)
23
37
  Playbook::Engine.root.join("app/pb_kits/playbook/pb_#{kit}", *args)
24
38
  end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "action_view/railtie"
4
- require "view_component/engine"
5
- require "webpacker/react"
3
+ require "sassc-rails"
4
+ require "slim-rails"
6
5
 
7
6
  module Playbook
8
7
  class Engine < ::Rails::Engine
@@ -14,15 +13,26 @@ module Playbook
14
13
 
15
14
  config.view_component.render_monkey_patch_enabled = false
16
15
 
17
- if config.respond_to?(:assets)
18
- config.assets.paths ||= []
19
- config.assets.paths << Playbook::Engine.root.join("fonts")
20
- config.assets.paths << Playbook::Engine.root.join("app/pb_kits/playbook/pb_*")
21
- end
16
+ config.assets.paths ||= []
17
+ config.assets.paths << Playbook::Engine.root.join("fonts")
18
+ config.assets.paths << Playbook::Engine.root.join("app/pb_kits/playbook/pb_*")
19
+
20
+ config.sass.load_paths ||= []
21
+ config.sass.load_paths << Playbook::Engine.root.join("app/pb_kits/playbook")
22
+
23
+ initializer "webpacker.proxy" do |app|
24
+ insert_middleware = begin
25
+ Playbook.webpacker.config.dev_server.present?
26
+ rescue
27
+ nil
28
+ end
29
+ next unless insert_middleware
22
30
 
23
- if config.respond_to?(:sass)
24
- config.sass.load_paths ||= []
25
- config.sass.load_paths << Playbook::Engine.root.join("app/pb_kits/playbook")
31
+ app.middleware.insert_before(
32
+ 0, Webpacker::DevServerProxy,
33
+ ssl_verify_none: true,
34
+ webpacker: Playbook.webpacker
35
+ )
26
36
  end
27
37
  end
28
38
  end