├── .gitignore ├── README.md ├── docs ├── add-robot-message.html ├── auto-form-detection.html ├── browser-autofill.html ├── click-edit-previous-answer.html ├── conditional-flow.html ├── empty-form.html ├── examples.html ├── exit-message.html ├── feature-cf-placeholder.html ├── files │ └── formless.json ├── formless.html ├── image-answers.html ├── images │ ├── favicon.ico │ ├── readme-cf.gif │ ├── share_img-twitter.jpg │ └── share_img.jpg ├── index.html ├── jquery.html ├── manual-start.html ├── multi-form.html ├── overwrite-dictionary.html ├── overwrite-styles.html ├── scripts │ ├── conversational-form-docs.min.js │ └── conversational-form-examples.min.js ├── styles │ ├── cf-theming.min.css │ └── conversational-form-docs.min.css ├── submit-callback.html ├── test-stress-elements.html ├── test-stress-instance-creation.html ├── validation.html ├── value-piping.html └── welcome-message.html ├── gulp-tasks ├── bower.js ├── images.js ├── package.json ├── scripts.js └── styles.js ├── gulpfile.js └── src ├── scripts ├── cf │ ├── ConversationalFormDocs.ts │ └── ConversationalFormExamples.ts ├── typings.json └── typings │ └── index.d.ts └── styles ├── cf ├── _cf-docs-variables.styl ├── _cf-variables.styl ├── cf-theming.styl ├── docs.styl ├── mixins │ └── _cf-mixins.styl └── ui │ ├── section-cf-context.styl │ ├── section-form.styl │ ├── section-info.styl │ ├── sticky-menu.styl │ └── switch.styl └── examples-boilerplate.styl /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Repository for Conversational Form documentation site 2 | 3 | This repository holds the latest Conversational Form documentation site. Check it out at [https://space10-community.github.io/conversational-form/](https://space10-community.github.io/conversational-form/) or the repo at [http://github.com/space10-community/conversational-form](http://github.com/space10-community/conversational-form). 4 | -------------------------------------------------------------------------------- /docs/add-robot-message.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 66 | 67 | 68 |
69 | 70 |

Conversational Form examples

71 | 72 |
73 | 77 |
78 | 79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
92 |
93 | 94 |
95 | 99 |
100 | 101 |
102 |
103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 |
114 | 115 |
116 |

117 | Add random robot response to Conversational Form 118 |

119 |

120 | 121 |

122 |
123 |
124 | 125 |
126 |
127 |
128 |
129 |
130 | 131 |
132 | 133 |
134 |
135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/auto-form-detection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |

Conversational Form examples

17 | 18 |
19 | 23 |
24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 |
39 | 40 |
41 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 |
62 |

63 | Auto form detection 64 |

65 |

66 | .... 67 |

68 |
69 |
70 | 71 |
72 |
73 | 74 | 75 |
76 | 77 |
78 | 79 |
80 |
81 | 82 |
83 | 84 |
85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/browser-autofill.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |

Conversational Form examples

17 | 18 |
19 | 23 |
24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 |
39 | 40 |
41 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 |
62 |

63 | Utilise browser auto-complete 64 |

65 |

66 | 1. Fill out the form on the right
67 | 2. Submit it, and use browser back button to come back here
68 | 3. The form is now prefilled with your previous data (mimic autocomplete)
69 |
70 | 71 |
72 |
73 | Video of auto-complete features 74 |

75 |
76 |
77 | 78 |
79 |
80 | 81 | 82 | 83 | 84 | 85 |
86 |
87 | Native form 88 |

89 | 90 |

91 | 92 | 93 |

94 |

95 | 96 | 97 |

98 |

99 | 100 | 101 |

102 |

103 | 104 |

105 | 106 | 107 |

108 |

109 | 110 | 111 |

112 |

113 | 114 | 115 |

116 |
117 |
118 | 119 |
120 |
121 | 122 |
123 |
124 | 125 |
126 | 127 |
128 |
129 | 130 | 131 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /docs/click-edit-previous-answer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |

Conversational Form examples

17 | 18 |
19 | 23 |
24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 |
39 | 40 |
41 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 |
62 |

63 | Edit previous submitted user answers 64 |

65 |

66 | Click on a user response to edit it. 67 |

68 |
69 |
70 | 71 |
72 |
73 | 74 | 75 | 76 | 77 |
78 | 79 | 80 |
  • 81 | 84 | 87 | 90 |
  • 91 | 92 | 93 |
    94 | 95 | 96 | 97 |
    98 |
    99 | 100 |
    101 | 102 |
    103 |
    104 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/conditional-flow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Conditional flow 64 |

    65 |

    66 | Using attr: cf-conditional to make conditional form flows. For documentation and more info see Wiki 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 | 75 |
    76 | 77 |
    78 | 81 | 82 | 85 | 86 | 89 |
    90 | 91 | 97 | 98 |
    99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
    108 | 109 | 110 | 116 | 117 | 118 |
    121 | 129 | 130 | 131 | 140 | 141 |
    142 | 143 | 144 | 145 | 146 | 147 | 154 | 155 |
    158 | 166 | 167 | 168 | 177 | 178 |
    179 | 180 | 181 | 186 | 187 | 188 | 196 | 197 | 202 | 203 | 208 | 209 | 210 | 215 | 216 |
    219 | 220 | 221 | 222 | 223 | 224 |
    225 | 226 | 231 |
    232 | 233 |
    234 |
    235 | 236 |
    237 | 238 |
    239 |
    240 | 241 | 242 | 271 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /docs/empty-form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    16 | 17 |

    Conversational Form examples

    18 | 19 |
    20 | 24 |
    25 | 26 |
    27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 41 |
    42 | 46 |
    47 | 48 |
    49 |
    50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
    61 | 62 |
    63 |

    64 | Test empty form element 65 |

    66 |

    67 | Check dev console. 68 |

    69 |
    70 |
    71 | 72 |
    73 |
    74 | 75 | 76 |
    77 |
    78 | 79 |
    80 |
    81 | 82 |
    83 | 84 |
    85 |
    86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/examples.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    16 | 17 |

    Conversational Form examples

    18 | 19 |
    20 | 24 |
    25 | 26 |
    27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
    39 |
    40 | 41 |
    42 | 46 |
    47 | 48 |
    49 |
    50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
    61 | 62 |
    63 |

    64 | Examples overview 65 |

    66 |

    67 | On the right you will find a list of examples. 68 |

    69 |
    70 |
    71 | 72 | 81 | 82 |
    83 |
    84 | 85 | 86 |
    87 |
    88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
    96 |
    97 | 98 |
    99 |
    100 | 101 |
    102 | 103 |
    104 |
    105 | 106 | 107 | -------------------------------------------------------------------------------- /docs/exit-message.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 28 | 29 | 30 |
    31 | 32 |

    Conversational Form examples

    33 | 34 |
    35 | 39 |
    40 | 41 |
    42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
    54 |
    55 | 56 |
    57 | 61 |
    62 | 63 |
    64 |
    65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 |
    76 | 77 |
    78 |

    79 | Add an exit message 80 |

    81 |

    82 | And style it like a champ 83 |

    84 |
    85 |
    86 | 87 |
    88 |
    89 | 90 |
    91 | 95 |
    96 | 97 |
    98 |
    99 | 100 |
    101 | 102 |
    103 |
    104 | 105 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /docs/feature-cf-placeholder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Custom placeholder text 64 |

    65 |

    66 | cf-input-placeholder="Place holder text.." 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 | 75 |
    76 | 77 |
    78 | 79 |
    80 |
    81 | 82 |
    83 | 84 |
    85 |
    86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/files/formless.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "preventAutoAppend": true, 4 | "submitCallback": "window.onFormlessSubmited" 5 | }, 6 | "tags": [ 7 | { 8 | "tag": "input", 9 | "type": "text", 10 | "value": "Prefilled value here", 11 | "cf-questions": "Input w. prefilled value" 12 | }, 13 | { 14 | "tag": "select", 15 | "cf-input-placeholder": "Choose one of the above", 16 | "multiple": "multiple", 17 | "cf-questions": "Choose multiple of the elements from the list", 18 | "children":[ 19 | { 20 | "tag": "option", 21 | "name": "option-dropdown-1", 22 | "cf-label": "option-1", 23 | "value": "-1" 24 | }, 25 | { 26 | "tag": "option", 27 | "name": "option-dropdown-1", 28 | "cf-label": "option-2", 29 | "value": "-2" 30 | } 31 | ] 32 | }, 33 | { 34 | "tag": "fieldset", 35 | "type": "Radio buttons", 36 | "cf-input-placeholder": "Choose one of the above", 37 | "cf-questions": "Choose one of the radioss", 38 | "children":[ 39 | { 40 | "tag": "input", 41 | "type": "radio", 42 | "name": "radio-buttons-1", 43 | "cf-label": "radio-1", 44 | "checked": "checked" 45 | }, 46 | { 47 | "tag": "input", 48 | "type": "radio", 49 | "name": "radio-buttons-1", 50 | "cf-label": "radio-2" 51 | } 52 | ] 53 | }, 54 | { 55 | "tag": "fieldset", 56 | "type": "Checkboxes", 57 | "cf-input-placeholder": "Choose above", 58 | "cf-questions": "Choose some checkboxes", 59 | "children":[ 60 | { 61 | "tag": "input", 62 | "type": "checkbox", 63 | "name": "checkboxes-buttons-1", 64 | "cf-label": "checkbox-1", 65 | "checked": "checked" 66 | }, 67 | { 68 | "tag": "input", 69 | "type": "checkbox", 70 | "name": "checkboxes-buttons-1", 71 | "cf-label": "checkbox-2" 72 | } 73 | ] 74 | }, 75 | { 76 | "tag": "input", 77 | "type": "password", 78 | "cf-input-placeholder": "Password field", 79 | "cf-questions": "Write a password" 80 | }, 81 | { 82 | "tag": "input", 83 | "type": "text", 84 | "pattern": ".{5,10}", 85 | "cf-input-placeholder": "Input w. pattern attribute", 86 | "cf-error": "No less than 5 and no more than 10 characters", 87 | "cf-questions": "Keep between 5-10 characters" 88 | }, 89 | { 90 | "tag": "input", 91 | "type": "text", 92 | "required": "required", 93 | "cf-questions": "This field is required (attribute)", 94 | "cf-error": "Please write something" 95 | }, 96 | { 97 | "tag": "input", 98 | "type": "text", 99 | "required": "required", 100 | "cf-questions": "This field uses window.testValidation", 101 | "cf-validation": "window.testValidation", 102 | "cf-error": "Check the window.testValidation method" 103 | } 104 | ] 105 | } -------------------------------------------------------------------------------- /docs/formless.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Formless form 64 |

    65 |

    66 | A Conversational Form generated from JSON, see file formless.json 67 |

    Options and tag attributes are 1:1 with a form tag. 68 |

    Example here also mimics calls to a server and injecting of server created tags. 69 |
    This can be used to validate and create custom flows Server Side. 70 |

    71 |
    72 |
    73 | 74 |
    75 |
    76 |

    No form, it's all JS

    77 |
    78 |
    79 |
    80 | 81 |
    82 | 83 |
    84 |
    85 | 86 | 87 | 88 | 89 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /docs/image-answers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Use images for checkbox and radio buttons 64 |

    65 |

    66 | Attribute cf-image 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
    81 | 82 |
    83 | 84 | 85 |
    86 | 87 |
    88 | 89 | 90 | 91 |
    92 | 93 |
  • 94 | 97 | 100 | 103 | 106 | 109 | 112 | 115 | 118 | 121 | 124 | 127 | 130 | 133 | 136 | 139 |
  • 140 | 141 | 142 |
    143 | 144 | 145 | 146 |
    147 |
    148 | 149 |
    150 | 151 |
    152 |
    153 | 154 | 155 | -------------------------------------------------------------------------------- /docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/space10-community/conversational-form-docs/50e5655220d430a9f83ccc2a086ce9cf146c6c2a/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/images/readme-cf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/space10-community/conversational-form-docs/50e5655220d430a9f83ccc2a086ce9cf146c6c2a/docs/images/readme-cf.gif -------------------------------------------------------------------------------- /docs/images/share_img-twitter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/space10-community/conversational-form-docs/50e5655220d430a9f83ccc2a086ce9cf146c6c2a/docs/images/share_img-twitter.jpg -------------------------------------------------------------------------------- /docs/images/share_img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/space10-community/conversational-form-docs/50e5655220d430a9f83ccc2a086ce9cf146c6c2a/docs/images/share_img.jpg -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Turning web forms into conversations 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
    48 | 49 |

    Conversational Form

    50 | 51 |
    52 | 56 |
    57 | 58 |
    59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
    71 |
    72 | 73 |
    74 | 78 |
    79 | 80 |
    81 |
    82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
    93 | 94 |

    95 | Conversational Form is licensed under MIT, 96 |
    documentation under CC BY 3.0. 97 |
    Development by Felix Nielsen, RWATGG. 98 |
    Design by Charlie Isslander and Norgram®. 99 | 100 |

    Concept by SPACE10. 101 |

    102 | 103 |
    104 |

    105 | Turning webforms into conversations. 106 |

    107 |

    108 | Conversational Form is an open-source concept by SPACE10 to easily turn any form element on a web page into a conversational form interface. 109 |

    Find some examples here or fill out the form on the right 👉 110 |

    111 | 112 | 113 |
    114 | 121 | 122 | 123 | 130 |
    131 | 132 | 153 |
    154 |
    155 | 156 |
    157 |
    158 |
    159 | 160 | 161 |
    162 | 163 |
    164 | 165 |
    166 | 170 |
    171 |
    172 | 176 |
    177 |
    178 | 182 |
    183 |
    184 | 188 |
    189 |
    190 | 191 |
    192 | 193 | 194 |
    195 | 196 |
    197 | 198 | 204 |
    205 | 206 |
    207 | 208 | 209 |
    210 | 211 |
    212 | 213 | 217 |
    218 | 219 |
    220 | 221 | 225 |
    226 | 227 | 228 |
    229 |
    230 | 231 |
    232 | 233 |
    234 |
    235 | 236 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /docs/jquery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
    18 | 19 |

    Conversational Form examples

    20 | 21 |
    22 | 26 |
    27 | 28 |
    29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
    41 |
    42 | 43 |
    44 | 48 |
    49 | 50 |
    51 |
    52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 | 64 |
    65 |

    66 | Init Conversational Form with jQuery 67 |

    68 |

    69 | jQuery plugin 70 |

    71 |
    72 |
    73 | 74 |
    75 |
    76 | 77 |
    78 | 82 |
    83 | 84 |
    85 |
    86 | 87 |
    88 | 89 |
    90 |
    91 | 92 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/manual-start.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Manual start the conversation 64 |

    65 |

    66 | Delay the Conversational Form start. 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 | 75 |
    76 | 77 |
    78 | 79 |
    80 |
    81 | 82 |
    83 | 84 |
    85 |
    86 | 87 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /docs/multi-form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 42 | 43 | 44 | 68 | 69 |
    70 | 71 |

    Conversational Form examples

    72 | 73 |
    74 | 78 |
    79 | 80 |
    81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |
    93 |
    94 | 95 |
    96 | 100 |
    101 | 102 |
    103 |
    104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
    115 | 116 |
    117 |

    118 | Multiple forms 119 |

    120 |

    121 | How to have multiple forms running on the same page 122 |

    123 |
    124 |
    125 | 126 |
    127 |
    128 | 129 |
    130 | 131 |
    132 | 133 |
    134 | 135 | 136 |
    137 | 138 |
    139 | 140 |
    141 | 142 |
    143 |
    144 | 145 |
    146 |
    147 | 148 |
    149 | 150 | 151 |
    152 | 153 |
    154 | 155 | 156 | 157 |
    158 | 159 |
    160 |
    161 |
    162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/overwrite-dictionary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Overwrite dictionary when instantiating Conversational Form 64 |

    65 |

    66 | .... 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 |
    75 | 76 | 77 | 78 |
    79 | 80 | 81 |
    82 | 83 |
    84 | 85 |
    86 |
    87 | 88 |
    89 | 90 |
    91 |
    92 | 93 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/scripts/conversational-form-docs.min.js: -------------------------------------------------------------------------------- 1 | var ConversationalForm=function(){function t(){}return t}(),ConversationalFormDocs=function(){function t(){this.introTimer=0,this.el=document.querySelector("main.content"),null!==document.getElementById("conversational-form-development")&&this.el.classList.add("development"),this.h1writer=new H1Writer({el:document.getElementById("writer")}),"none"!=window.getComputedStyle(document.getElementById("small-screen-menu")).getPropertyValue("display")?this.introFlow1():this.introFlow2()}return t.prototype.introFlow1=function(){var t=this,e=null!==document.getElementById("conversational-form-development");this.introTimer=setTimeout(function(){t.toggleMenuState(),t.h1writer.start(),t.introTimer=setTimeout(function(){t.toggleConversation()},e?0:2500)},e?0:500)},t.prototype.introFlow2=function(){var t=this,e=null!==document.getElementById("conversational-form-development");this.h1writer.start(),this.introTimer=setTimeout(function(){document.getElementById("info").classList.add("show"),t.introTimer=setTimeout(function(){document.querySelector("section[role='form']").classList.add("show"),document.getElementById("cf-toggle-btn").classList.add("show"),t.introTimer=setTimeout(function(){t.toggleConversation()},e?0:1500)},e?0:3e3)},e?0:1500)},t.prototype.toggleMenuState=function(){return this.el.classList.toggle("menu-toggle",!this.el.classList.contains("menu-toggle"))&&this.el.classList.remove("cf-toggle"),!1},t.prototype.toggleConversation=function(){var t=this;return clearTimeout(this.introTimer),this.el.classList.contains("cf-toggle")?this.el.classList.remove("cf-toggle"):(this.cf||(this.cf=new window.cf.ConversationalForm({formEl:document.getElementById("cf-form"),context:document.getElementById("cf-context"),robotImage:"data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZyBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzY0LjAwMDAwMCwgLTUzMC4wMDAwMDApIiBmaWxsPSIjMjIyMjIyIj4KICAgICAgICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzUzLjAwMDAwMCwgNTE5LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPHJlY3QgeD0iMTEiIHk9IjExIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvcmVjdD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+",userImage:"data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIxNnB4IiB2aWV3Qm94PSIwIDAgMjAgMTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZyBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTM3MS4wMDAwMDAsIC02MTAuMDAwMDAwKSIgZmlsbD0iI0ZGRkZGRiI+CiAgICAgICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyNzQuMDAwMDAwLCA1OTkuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cG9seWdvbiBwb2ludHM9IjEwNyAxMSAxMTcgMjcgOTcgMjciPjwvcG9seWdvbj4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+",submitCallback:function(){},flowStepCallback:function(e,s,i){if(e.tag.domElement)if("repeat"==e.tag.domElement.getAttribute("name"))location.reload();else if("submit-form"==e.tag.domElement.getAttribute("name")){var n=new XMLHttpRequest;n.addEventListener("load",function(){t.cf.addRobotChatResponse("We received your submission 🙌"),s()}),n.open("POST",document.getElementById("cf-form").getAttribute("action")),n.setRequestHeader("accept","application/javascript"),n.setRequestHeader("Content-Type","application/json"),n.send(JSON.stringify(t.cf.getFormData(!0)))}else s();else s()}})),this.cf.focus(),setTimeout(function(){t.el.classList.remove("menu-toggle"),t.el.classList.add("cf-toggle")},10)),!1},t.start=function(){t.instance||(window.conversationalFormDocs=new t)},t}(),H1Writer=function(){function t(t){this.progress=0,this.progressTarget=0,this.str="",this.strs=["...","TBD"],this.step=0,this.el=t.el,this.strs[1]=this.el.innerHTML,this.el.innerHTML="",this.el.classList.add("show")}return t.prototype.start=function(){this.progress=0,this.progressTarget=1,this.str=this.strs[this.step],this.render()},t.prototype.nextStep=function(){0==this.progressTarget&&this.step++,this.str=this.strs[this.step],this.progressTarget=0==this.progressTarget?1:0,this.render()},t.prototype.render=function(){var t=this;this.progress+=(this.progressTarget-this.progress)*(0==this.step?.15:.09);var e=this.str.substr(0,Math.round(this.progress*this.str.length));this.el.innerHTML=e,Math.abs(this.progress-this.progressTarget)<=.01?(cancelAnimationFrame(this.rAF),this.step<1&&setTimeout(function(){t.nextStep()},500)):this.rAF=window.requestAnimationFrame(function(){return t.render()})},t}();"complete"==document.readyState?ConversationalFormDocs.start():window.addEventListener("load",function(){ConversationalFormDocs.start()},!1); -------------------------------------------------------------------------------- /docs/scripts/conversational-form-examples.min.js: -------------------------------------------------------------------------------- 1 | var ConversationalFormExamples=function(){function t(){this.introTimer=0,this.hasCalledExamplesInit=!1,this.el=document.querySelector("main.content"),null!==document.getElementById("conversational-form-development")&&this.el.classList.add("development"),this.h1writer=new H1ExamplesWriter({el:document.getElementById("writer")}),"none"!=window.getComputedStyle(document.getElementById("small-screen-menu")).getPropertyValue("display")?this.introFlow1():this.introFlow2()}return t.prototype.introFlow1=function(){var t=this,e=null!==document.getElementById("conversational-form-development");this.introTimer=setTimeout(function(){t.toggleMenuState(),t.h1writer.start(),t.introTimer=setTimeout(function(){document.getElementById("examples-script").getAttribute("manual-init")||t.toggleConversation()},e?0:2500)},e?0:500)},t.prototype.introFlow2=function(){var t=this,e=null!==document.getElementById("conversational-form-development");this.h1writer.start(),this.introTimer=setTimeout(function(){document.getElementById("info").classList.add("show"),t.introTimer=setTimeout(function(){document.querySelector("section[role='form']").classList.add("show"),document.getElementById("cf-toggle-btn").classList.add("show"),t.introTimer=setTimeout(function(){document.getElementById("examples-script").getAttribute("manual-init")||t.toggleConversation()},e?0:1500)},e?0:3e3)},e?0:1500)},t.prototype.toggleMenuState=function(){return this.el.classList.toggle("menu-toggle",!this.el.classList.contains("menu-toggle"))&&this.el.classList.remove("cf-toggle"),!1},t.prototype.toggleConversation=function(){var t=this;return!this.hasCalledExamplesInit&&window.initExample&&(window.initExample(),this.hasCalledExamplesInit=!0),clearTimeout(this.introTimer),this.el.classList.contains("cf-toggle")?this.el.classList.remove("cf-toggle"):setTimeout(function(){t.el.classList.remove("menu-toggle"),t.el.classList.add("cf-toggle")},10),!1},t.start=function(){t.instance||(window.conversationalFormExamples=new t)},t}(),H1ExamplesWriter=function(){function t(t){this.progress=0,this.progressTarget=0,this.str="",this.strs=["...","TBD"],this.step=0,this.el=t.el,this.strs[1]=this.el.innerHTML,this.el.innerHTML="",this.el.classList.add("show")}return t.prototype.start=function(){this.progress=0,this.progressTarget=1,this.str=this.strs[this.step],this.render()},t.prototype.nextStep=function(){0==this.progressTarget&&this.step++,this.str=this.strs[this.step],this.progressTarget=0==this.progressTarget?1:0,this.render()},t.prototype.render=function(){var t=this;this.progress+=(this.progressTarget-this.progress)*(0==this.step?.15:.09);var e=this.str.substr(0,Math.round(this.progress*this.str.length));this.el.innerHTML=e,Math.abs(this.progress-this.progressTarget)<=.01?(cancelAnimationFrame(this.rAF),this.step<1&&setTimeout(function(){t.nextStep()},500)):this.rAF=window.requestAnimationFrame(function(){return t.render()})},t}();"complete"==document.readyState?ConversationalFormExamples.start():window.addEventListener("load",function(){ConversationalFormExamples.start()},!1); -------------------------------------------------------------------------------- /docs/styles/cf-theming.min.css: -------------------------------------------------------------------------------- 1 | main.content .conversational-form{font-family:Helvetica Neue,Helvetica;font-style:normal}main.content .conversational-form cf-chat-response{padding-top:0;min-width:200px}@media only screen and (max-width:769px){main.content .conversational-form cf-chat-response{max-width:83%}}main.content .conversational-form cf-chat-response text{font-weight:900;min-height:42px;font-size:13px}main.content .conversational-form cf-chat-response thumb{background-color:#ebebeb;height:42px;width:42px}main.content .conversational-form cf-chat-response:not(:last-of-type){margin-bottom:10px}main.content .conversational-form cf-chat-response.robot{padding-left:48px}main.content .conversational-form cf-chat-response.robot text{background:#ebebeb;color:#222;border-radius:4px 20px 20px 20px}main.content .conversational-form cf-chat-response.robot thumb{background-color:#ebebeb;background-size:20px 20px;background-repeat:no-repeat}main.content .conversational-form cf-chat-response.user{padding-right:48px}main.content .conversational-form cf-chat-response.user text{background:#222;color:#fff;border-radius:20px 4px 20px 20px}main.content .conversational-form cf-chat-response.user thumb{background-color:#222;background-size:20px 16px;background-repeat:no-repeat;background-position:11px 12px}main.content .conversational-form cf-input input,main.content .conversational-form cf-input textarea{border-radius:40px;min-height:57px;font-size:14px;padding:19px 60px 19px 40px;height:56px;color:rgba(34,34,34,.4);font-weight:900}@media only screen and (min-width:769px){main.content .conversational-form cf-input input,main.content .conversational-form cf-input textarea{font-size:16px}}main.content .conversational-form cf-input input:not(:focus),main.content .conversational-form cf-input textarea:not(:focus){box-shadow:0 0 1px rgba(58,58,58,.5)}main.content .conversational-form cf-input-button{background:#222;height:42px;width:42px;border:none}main.content .conversational-form cf-input-button .cf-icon-progress{background-image:url("data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMThweCIgaGVpZ2h0PSIxOXB4IiB2aWV3Qm94PSIwIDAgMTggMTkiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZyBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTM3Mi4wMDAwMDAsIC05NDUuMDAwMDAwKSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjIiPgogICAgICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3NTEuMDAwMDAwLCA5MjcuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MjIuMDAwMDAwLCAxOS4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOC4xNDAzNTA4OCwyLjEwOTE4MTE0IEw4LjE0MDM1MDg4LDE2LjA4MDkzODUiIGlkPSJMaW5lIiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlsaW5lIGlkPSJSZWN0YW5nbGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuOTkzODAzLCA4LjA2ODc0NSkgcm90YXRlKC0zMTUuMDAwMDAwKSB0cmFuc2xhdGUoLTcuOTkzODAzLCAtOC4wNjg3NDUpICIgcG9pbnRzPSIyLjYyNTkxMzI4IDEzLjQ4Njk1OCAyLjYyNTkxMzI4IDIuNjUwNTMxMjEgMi42MjU5MTMyOCAyLjY1MDUzMTIxIDEzLjM2MTY5MjEgMi42NTA1MzEyMSI+PC9wb2x5bGluZT4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+");background-size:18px 19px}main.content .conversational-form cf-input-button.loading:after{border:2px solid #1ed97b}main.content .conversational-form .cf-button{color:#222;border-color:#ddd;transition:border-color .75s cubic-bezier(.215,.61,.355,1),color .75s cubic-bezier(.215,.61,.355,1);background:0 0!important;font-weight:900;line-height:1.2}main.content .conversational-form .cf-button>div{padding:14px 24px}main.content .conversational-form .cf-button cf-radio{background:rgba(34,34,34,.2)}main.content .conversational-form .cf-button.highlight,main.content .conversational-form .cf-button.selected,main.content .conversational-form .cf-button:focus,main.content .conversational-form .cf-button:hover,main.content .conversational-form .cf-button[checked=checked]{border-color:#6f6f6f;color:#595959}main.content .conversational-form .cf-button.highlight cf-radio,main.content .conversational-form .cf-button.selected cf-radio,main.content .conversational-form .cf-button:focus cf-radio,main.content .conversational-form .cf-button:hover cf-radio,main.content .conversational-form .cf-button[checked=checked] cf-radio{background:#222}main.content .conversational-form cf-list-button:after{background-image:none;background:#000;width:5px;height:5px;border-radius:50%} -------------------------------------------------------------------------------- /docs/styles/conversational-form-docs.min.css: -------------------------------------------------------------------------------- 1 | .form-outer{display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:box;display:flex}.form-outer>#form{-webkit-align-self:flex-end;align-self:flex-end;-ms-flex-item-align:end}.form-outer>h2{position:absolute;bottom:20px;left:20px}a,abbr,acronym,address,applet,big,blockquote,body,caption,cite,code,dd,del,dfn,div,dl,dt,em,fieldset,form,h1,h2,h3,h4,h5,h6,html,iframe,img,ins,kbd,label,legend,li,object,ol,p,pre,q,s,samp,small,span,strike,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,tt,ul,var{margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-family:inherit;font-size:100%;vertical-align:baseline}body{line-height:1;color:#000;background:#fff}ol,ul{list-style:none}table{border-collapse:separate;border-spacing:0;vertical-align:middle}caption,td,th{text-align:left;font-weight:400;vertical-align:middle}a img{border:none}html{overflow-y:auto}body{background:#222}body,html{position:relative;width:100%;height:100%;padding:0;margin:0}main.content{font-family:Helvetica Neue,Helvetica;font-style:normal;-webkit-font-smoothing:antialiased;min-height:100%;height:auto;width:100%;position:relative;overflow:hidden;display:block}main.content *{-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}main.content *,main.content :after,main.content :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;outline:0}main.content a,main.content a:active,main.content a:focus{color:currentColor}@media only screen and (min-width:769px){main.content .switch-btn#cf-toggle-btn{position:absolute;top:40px;z-index:500;right:32px;-webkit-transform:translateX(400px);-moz-transform:translateX(400px);-o-transform:translateX(400px);-ms-transform:translateX(400px);transform:translateX(400px);will-change:transform;-webkit-transition:-webkit-transform 375ms cubic-bezier(.215,.61,.355,1);-moz-transition:-moz-transform 375ms cubic-bezier(.215,.61,.355,1);-o-transition:-o-transform 375ms cubic-bezier(.215,.61,.355,1);-ms-transition:-ms-transform 375ms cubic-bezier(.215,.61,.355,1);transition:transform 375ms cubic-bezier(.215,.61,.355,1)}main.content .switch-btn#cf-toggle-btn.show{-webkit-transform:translateX(0);-moz-transform:translateX(0);-o-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}}@media only screen and (max-width:769px){main.content .switch-btn#cf-toggle-btn{display:none}}main.content.cf-toggle:not(.menu-toggle) section[role=cf-context]{pointer-events:auto;opacity:1}main.content section[role=cf-context]{position:absolute;z-index:250;pointer-events:none;overflow:hidden;height:100%;width:100%;top:0;left:0;opacity:0;will-change:opacity;transition:opacity 375ms cubic-bezier(.215,.61,.355,1)}@media only screen and (min-width:769px){main.content section[role=cf-context]{width:50%;z-index:499;right:0;left:auto}}main.content section[role=cf-context] .close-btn{position:absolute;z-index:500;right:24px;top:18px;width:24px;height:24px}main.content section[role=cf-context] .close-btn svg{width:100%;height:100%}main.content section[role=form]{position:absolute;background:#fff;top:0;left:0;z-index:50;height:100%;width:100%;padding:27px;padding-top:88px;display:flex;flex-flow:row;justify-content:flex-start}@media only screen and (min-width:769px){main.content section[role=form]{padding:37px 40px;width:50vw;z-index:250;right:0;left:auto;will-change:opacity;transition:opacity 375ms cubic-bezier(.215,.61,.355,1);opacity:0}main.content section[role=form].show{opacity:1}}main.content section[role=form] .close-btn{position:absolute;z-index:499;right:24px;top:18px;width:24px;height:24px}main.content section[role=form] .close-btn svg{width:100%;height:100%}main.content section[role=form] form{align-self:flex-end;width:100%}main.content section[role=form] fieldset{margin-bottom:20px;max-width:400px}main.content section[role=form] fieldset:nth-child(6),main.content section[role=form] fieldset:nth-child(7){display:none}main.content section[role=form] fieldset>*{display:block;width:100%}main.content section[role=form] fieldset button{max-width:50px}main.content section[role=form] fieldset label{font-weight:900;font-size:calc(9px + ((12 - 9) * ((100vw - 320px)/ (1600 - 320))));margin-bottom:4px}main.content section[role=form] fieldset input{padding:8px}main.content section[role=form] fieldset input[type=email],main.content section[role=form] fieldset input[type=text]{border:1px solid #222}main.content section[role=form] fieldset select{-webkit-appearance:none;-webkit-border-radius:0;background:url("data:image/svg+xml;utf8,");background-repeat:no-repeat;background-size:60% 60%;background-position:160% 50%;padding:8px;height:31px;font-size:calc(9px + ((12 - 9) * ((100vw - 320px)/ (1600 - 320))));border-radius:0;background-color:#fff;border-color:#000}main.content section[role=form] fieldset .radio{margin-left:30px}main.content.menu-toggle:not(.cf-toggle) section[role=info]{transform:translateX(0)}main.content section[role=info]{background:#222;position:absolute;left:0;top:0;z-index:51;color:#fff;height:100%;width:100%;transform:translateX(-100%);will-change:transform;transition:transform 375ms cubic-bezier(.215,.61,.355,1);padding:27px}main.content section[role=info] a{opacity:1}@media only screen and (min-width:769px){main.content section[role=info] a{will-change:opacity;transition:opacity .75s cubic-bezier(.215,.61,.355,1)}main.content section[role=info] a:hover{opacity:.5}}@media only screen and (max-width:769px){main.content section[role=info]{transform:translateX(100%);z-index:499}}@media only screen and (min-width:769px){main.content section[role=info]{padding:37px 40px;transform:translateX(0);will-change:opacity;transition:opacity .75s cubic-bezier(.215,.61,.355,1)}main.content section[role=info]>article h1{opacity:0}main.content section[role=info]>article h1.show{opacity:1}main.content section[role=info] .github-button__outer{visibility:hidden}main.content section[role=info] footer>a svg,main.content section[role=info] footer>h3,main.content section[role=info]>article .github-button__outer iframe,main.content section[role=info]>article h2,main.content section[role=info]>h3{will-change:opacity;transition:opacity .75s cubic-bezier(.215,.61,.355,1);opacity:0}main.content section[role=info]>h3{transition-delay:2s}main.content section[role=info]>article>h2{transition-delay:.5s}main.content section[role=info]>article>.github-button__outer iframe:nth-child(1){transition-delay:.7s}main.content section[role=info]>article>.github-button__outer iframe:nth-child(2){transition-delay:.9s}main.content section[role=info]>article footer>h3{transition-delay:2s}main.content section[role=info]>article footer>a svg{transition-delay:3s}main.content section[role=info].show .github-button__outer{visibility:visible}main.content section[role=info].show>article h2,main.content section[role=info].show>h3{opacity:.7}main.content section[role=info].show footer>a svg,main.content section[role=info].show footer>h3,main.content section[role=info].show>article .github-button__outer iframe{opacity:1}}main.content section[role=info] .close-btn{display:none}@media only screen and (max-width:769px){main.content section[role=info] .close-btn{display:block;position:absolute;z-index:499;right:24px;top:18px;width:24px;height:24px;border:none;background:0 0;padding:0;margin:0}main.content section[role=info] .close-btn svg{width:100%;height:100%}}main.content section[role=info]>h3{line-height:1.25;font-weight:900;font-size:calc(9px + ((12 - 9) * ((100vw - 320px)/ (1600 - 320))))}main.content section[role=info] article{position:absolute;bottom:27px;width:calc(100% - 54px)}@media only screen and (min-width:769px){main.content section[role=info] article{bottom:37px;width:calc(50% - 80px)}}main.content section[role=info] article h1{line-height:1.1;letter-spacing:.5px;font-weight:900;font-size:calc(35px + ((50 - 35) * ((100vw - 320px)/ (1600 - 320))));padding-right:20px;max-width:800px}main.content section[role=info] article h2{line-height:1.2;letter-spacing:-.1px;font-weight:400;font-size:calc(12px + ((13 - 12) * ((100vw - 320px)/ (1600 - 320))));max-width:calc(270px + ((320 - 270) * ((100vw - 320px)/ (1600 - 320))));margin-top:calc(11px + ((30 - 11) * ((100vw - 320px)/ (1600 - 320))));margin-bottom:calc(22px + ((60 - 22) * ((100vw - 320px)/ (1600 - 320))))}main.content section[role=info] article .github-button__outer{height:28px}main.content section[role=info] article .github-button__outer iframe:first-of-type{margin-right:10px}main.content section[role=info] article footer{width:100%;position:relative;margin-top:calc(65px + ((138 - 65) * ((100vw - 320px)/ (1600 - 320))))}main.content section[role=info] article footer h3{font-weight:900;font-size:calc(11px + ((13 - 11) * ((100vw - 320px)/ (1600 - 320))))}main.content section[role=info] article footer>a{position:absolute;right:0;top:0;height:16px;width:calc(51px + ((58 - 51) * ((100vw - 320px)/ (1600 - 320))))}main.content section[role=info] article footer>a svg{width:100%;height:100%}main.content.menu-toggle>menu{transform:translateY(-100%)}main.content>menu{background:#222;position:fixed;z-index:500;padding:0;margin:0;height:61px;width:100%;color:#fff;left:0;top:0;will-change:transform;transition:transform 375ms cubic-bezier(.215,.61,.355,1)}@media only screen and (min-width:769px){main.content>menu{display:none}}main.content>menu h2{font-weight:900;transform:translateY(-50%);position:absolute;left:24px;top:50%;font-size:calc(14px + ((16 - 14) * ((100vw - 320px)/ (1600 - 320))))}main.content>menu .switch-btn{position:absolute;right:63px;top:16px}main.content>menu .hamburger-btn{position:absolute;height:14px;width:29px;right:21px;top:23px}main.content>menu .hamburger-btn svg{width:100%;height:100%}main.content.cf-toggle .switch-btn:after{opacity:0}main.content.cf-toggle .switch-btn:before{opacity:1}main.content.cf-toggle .switch-btn .switch .slider{background-color:#1ed97b}main.content.cf-toggle .switch-btn .switch .slider{box-shadow:0 0 1px #1ed97b}main.content.cf-toggle .switch-btn .switch .slider:before{transform:translateX(26px)}@media only screen and (min-width:769px){main.content.cf-toggle .switch-btn .switch .slider:before{transform:translateX(39px)}}main.content .switch-btn{font-size:13px;font-weight:900;border:none;background:0 0;padding:0;margin:0}main.content .switch-btn:after{content:attr(data-label);opacity:1}main.content .switch-btn:before{content:attr(data-label-toggled);opacity:0}main.content .switch-btn:after,main.content .switch-btn:before{display:block;position:absolute;left:-11px;top:50%;transform:translateX(-100%) translateY(-50%);white-space:nowrap;will-change:opacity;transition:opacity 375ms cubic-bezier(.215,.61,.355,1)}main.content .switch-btn .switch{position:relative;display:inline-block;width:56px;height:28px;padding:0;margin:0;border:none;background:0 0;cursor:pointer}@media only screen and (min-width:769px){main.content .switch-btn .switch{width:80px;height:40px}}main.content .switch-btn .switch input{display:none}main.content .switch-btn .switch .slider{position:absolute;pointer-events:none;top:0;left:0;right:0;bottom:0;background-color:#ccc;will-change:transform,background-color;transition:transform 375ms cubic-bezier(.215,.61,.355,1),background-color 375ms cubic-bezier(.215,.61,.355,1)}main.content .switch-btn .switch .slider.round{border-radius:34px}main.content .switch-btn .switch .slider.round:before{border-radius:50%}main.content .switch-btn .switch .slider:before{position:absolute;content:"";height:20px;width:20px;left:4px;bottom:4px;background-color:#fff;transition:transform 375ms cubic-bezier(.215,.61,.355,1)}@media only screen and (min-width:769px){main.content .switch-btn .switch .slider:before{height:30px;width:30px;left:5px;bottom:5px}} -------------------------------------------------------------------------------- /docs/submit-callback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | How to catch the submit event 64 |

    65 |

    66 | .... 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 |
    75 | 76 |
    77 | 78 |
    79 |
    80 | 81 |
    82 | 83 |
    84 |
    85 | 86 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /docs/test-stress-instance-creation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Initialise and remove 100 Conversational Form instances to test creation process. 64 |

    65 |

    66 | Check dev tools and output for performance marker. 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 | 75 |
    76 |
    77 | 78 | 79 | 80 | 81 |
    82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
    90 | 91 |
    92 |
    93 | 94 |
    95 | 96 |
    97 |
    98 | 99 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/validation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Different validation strategies 64 |

    65 |

    66 | Simple questions about Sherlock Holmes. 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 | 75 | 76 |
    77 | 78 |
    79 | 80 |
    81 | 82 | 83 |
    84 | 85 | 86 |

    87 |
    88 | 89 | 92 | 93 | 99 | 100 | 109 | 110 |
    111 | 112 | 113 | 114 | 115 | 116 | 117 |
    118 | 119 |
    120 | 121 |
    122 |
    123 | 124 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /docs/value-piping.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 16 |

    Conversational Form examples

    17 | 18 |
    19 | 23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
    38 |
    39 | 40 |
    41 | 45 |
    46 | 47 |
    48 |
    49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 |
    62 |

    63 | Value piping 64 |

    65 |

    66 | Map valus across tags using the id attribute. 67 |

    68 |
    69 |
    70 | 71 |
    72 |
    73 | 74 |
    75 | 76 | 77 | 78 | 79 |
    80 | 81 |
    82 |
    83 | 84 |
    85 | 86 |
    87 |
    88 | 89 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /docs/welcome-message.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 21 | 22 |
    23 | 24 |

    Conversational Form examples

    25 | 26 |
    27 | 31 |
    32 | 33 |
    34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
    46 |
    47 | 48 |
    49 | 53 |
    54 | 55 |
    56 |
    57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
    68 | 69 |
    70 |

    71 | Add a welcome message 72 |

    73 |

    74 | And style it like a champ 75 |

    76 |
    77 |
    78 | 79 |
    80 |
    81 | 82 |
    83 | 87 | 88 | 89 |
    90 | 91 |
    92 |
    93 | 94 |
    95 | 96 |
    97 |
    98 | 99 | 100 | -------------------------------------------------------------------------------- /gulp-tasks/bower.js: -------------------------------------------------------------------------------- 1 | //var gulp = require('gulp'); 2 | var bower = require('gulp-bower'); 3 | 4 | global.gulp.task('bower', function() { 5 | return bower({ 6 | cwd: "./" 7 | }); 8 | }); -------------------------------------------------------------------------------- /gulp-tasks/images.js: -------------------------------------------------------------------------------- 1 | var changed = require('gulp-changed'); 2 | var livereload = require('gulp-livereload'); 3 | var notify = require("gulp-notify"); 4 | 5 | global.gulp.task('copy-images', function() { 6 | var src = global.srcFolder+"/images/**/*"; 7 | var dst = global.buildFolder; 8 | 9 | var stream = global.gulp.src(src) 10 | .pipe(global.gulp.dest(dst)) 11 | .pipe(changed(dst)) 12 | .pipe(livereload()) 13 | .pipe(notify("Files copied.")); 14 | 15 | return stream; 16 | }); -------------------------------------------------------------------------------- /gulp-tasks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "space10", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "gulp": "*" 6 | }, 7 | "devDependencies": { 8 | "gulp-bower": "*", 9 | "gulp-changed": "*", 10 | "gulp-clean-css": "^3.0.2", 11 | "gulp-concat": "^2.6.0", 12 | "gulp-flatten": "*", 13 | "gulp-insert-lines": "*", 14 | "gulp-livereload": "*", 15 | "gulp-notify": "*", 16 | "gulp-prompt": "*", 17 | "gulp-rename": "^1.2.2", 18 | "gulp-stylus": "*", 19 | "gulp-sync": "^0.1.4", 20 | "gulp-typescript": "*", 21 | "gulp-uglify": "^2.0.0", 22 | "gulp-util": "*", 23 | "nib": "*", 24 | "rupture": "*", 25 | "stream": "*", 26 | "typescript": "*" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gulp-tasks/scripts.js: -------------------------------------------------------------------------------- 1 | var typescript = require('gulp-typescript'); 2 | var flatten = require('gulp-flatten'); 3 | var changed = require('gulp-changed'); 4 | var gutil = require('gulp-util'); 5 | var livereload = require('gulp-livereload'); 6 | var notify = require("gulp-notify"); 7 | var concat = require('gulp-concat'); 8 | var rename = require('gulp-rename'); 9 | var uglify = require('gulp-uglify'); 10 | 11 | function swallowError(error) { 12 | // If you want details of the error in the console 13 | gutil.log(error.toString()); 14 | gutil.beep(); 15 | this.emit('end'); 16 | } 17 | 18 | global.gulp.task('typescript', function() { 19 | var src = [ 20 | global.srcFolder + "../src/scripts/**/*.ts", 21 | "!" + global.srcFolder + "../src/scripts/typings/**/*.d.ts" 22 | ]; 23 | var dst = global.buildFolder + "../build"; 24 | 25 | var stream = global.gulp.src(src) 26 | .pipe(changed(dst,{ 27 | extension: '.js' 28 | })) 29 | .pipe(typescript({ 30 | noImplicitAny: true, 31 | target: "ES5", 32 | module: "none"//AMD... etc. 33 | })) 34 | .on('error', swallowError) 35 | .pipe(global.gulp.dest(dst)) 36 | .pipe(livereload()) 37 | .pipe(notify("Typescript compiled.")); 38 | 39 | return stream 40 | }); 41 | 42 | global.gulp.task('scripts-build', ['scripts-build-docs', 'scripts-build-examples'], function(){ 43 | }); 44 | 45 | global.gulp.task('scripts-build-docs', ['typescript'], function(){ 46 | // build order is important in a inheritance world 47 | var src = [ 48 | global.buildFolder + "cf/ConversationalFormDocs.js" 49 | ]; 50 | var dst = global.srcFolder + "../docs/scripts"; 51 | 52 | var stream = global.gulp.src(src) 53 | .pipe(concat('conversational-form-docs.js')) 54 | .pipe(uglify()) 55 | .pipe(rename({suffix: '.min'})) 56 | .pipe(global.gulp.dest(dst)); 57 | 58 | return stream; 59 | }); 60 | 61 | global.gulp.task('scripts-build-examples', ['typescript'], function(){ 62 | // build order is important in a inheritance world 63 | var src = [ 64 | global.buildFolder + "cf/ConversationalFormExamples.js" 65 | ]; 66 | var dst = global.srcFolder + "../docs/scripts"; 67 | 68 | var stream = global.gulp.src(src) 69 | .pipe(concat('conversational-form-examples.js')) 70 | .pipe(uglify()) 71 | .pipe(rename({suffix: '.min'})) 72 | .pipe(global.gulp.dest(dst)); 73 | 74 | return stream; 75 | }); -------------------------------------------------------------------------------- /gulp-tasks/styles.js: -------------------------------------------------------------------------------- 1 | var rupture = require('rupture'); 2 | var nib = require('nib'); 3 | var stylus = require('gulp-stylus'); 4 | var flatten = require('gulp-flatten'); 5 | var changed = require('gulp-changed'); 6 | var gutil = require('gulp-util'); 7 | var livereload = require('gulp-livereload'); 8 | var notify = require("gulp-notify"); 9 | var concat = require('gulp-concat'); 10 | var cleanCSS = require('gulp-clean-css'); 11 | var rename = require('gulp-rename'); 12 | 13 | function swallowError(error) { 14 | // If you want details of the error in the console 15 | gutil.log(error.toString()); 16 | gutil.beep(); 17 | this.emit('end'); 18 | } 19 | 20 | /** 21 | * OBS: seperate build tasks out so we can split the project into smaller pieces later. 22 | */ 23 | 24 | global.gulp.task('stylus', function(){ 25 | var src = [ 26 | global.srcFolder + "styles/**/*.styl", 27 | "!" + global.srcFolder + "styles/**/_cf*.styl" 28 | ] 29 | var dst = global.srcFolder + "../build"; 30 | 31 | var stream = global.gulp.src(src) 32 | .pipe(changed(dst, { 33 | extension: '.css' 34 | })) 35 | .pipe(stylus({ 36 | use: [nib(), rupture()], 37 | errors: true 38 | })) 39 | .pipe(global.gulp.dest(dst)); 40 | 41 | return stream; 42 | }); 43 | 44 | global.gulp.task('styles-build', ['stylus'], function(){ 45 | var src = [ 46 | global.srcFolder + "../build/**/*.css", 47 | global.srcFolder + "../build/cf/docs.css", 48 | global.srcFolder + "../build/cf/ui/section-cf-context.css", 49 | global.srcFolder + "../build/cf/ui/section-form.css", 50 | global.srcFolder + "../build/cf/ui/section-info.css", 51 | global.srcFolder + "../build/cf/ui/sticky-menu.css", 52 | global.srcFolder + "../build/cf/ui/switch.css", 53 | global.srcFolder + "../build/examples-boilerplate.css", 54 | 55 | "!" + global.srcFolder + "../build/**/cf-theming.css" 56 | ] 57 | 58 | var dst = global.srcFolder + "../docs/styles"; 59 | 60 | var stream = global.gulp.src(src) 61 | .pipe(concat('conversational-form-docs.css')) 62 | .pipe(cleanCSS()) 63 | .pipe(rename({suffix: '.min'})) 64 | .pipe(global.gulp.dest(dst)); 65 | 66 | 67 | stream = global.gulp.src([global.srcFolder + "../build/**/cf-theming.css"]) 68 | .pipe(concat('cf-theming.css')) 69 | .pipe(cleanCSS()) 70 | .pipe(rename({suffix: '.min'})) 71 | .pipe(global.gulp.dest(dst)); 72 | 73 | return stream; 74 | }); -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | global.gulp = require('gulp'); 2 | var fs = require('fs'); 3 | var livereload = require('./gulp-tasks/node_modules/gulp-livereload'); 4 | var gulpsync = require('./gulp-tasks/node_modules/gulp-sync')(global.gulp); 5 | 6 | var package = JSON.parse(fs.readFileSync('gulp-tasks/package.json')); 7 | 8 | // include task files 9 | require("./gulp-tasks/styles"); 10 | require("./gulp-tasks/scripts"); 11 | require("./gulp-tasks/images"); 12 | require("./gulp-tasks/bower"); 13 | 14 | //options 15 | var rootPath = "./"; 16 | 17 | var srcFolder = rootPath + 'src/'; 18 | global.srcFolder = srcFolder; 19 | 20 | var buildFolder = rootPath + 'build/'; 21 | global.buildFolder = buildFolder; 22 | 23 | var distFolder = rootPath + 'dist/'; 24 | global.distFolder = distFolder; 25 | 26 | var tasks = ['bower', 'scripts-docs-build', 'scripts-examples-build', 'styles-docs-build', 'styles-examples-build', 'copy-images']; 27 | 28 | // Watch Files For Changes 29 | global.gulp.task('watch', tasks, function() { 30 | livereload.listen(); 31 | 32 | console.log("Watch task started — development"); 33 | 34 | global.gulp.watch(srcFolder + '/images/**/*', ['copy-images']); 35 | 36 | global.gulp.watch(srcFolder + '/scripts/**/*.ts', ['typescript']); 37 | 38 | global.gulp.watch(srcFolder + '/styles/**/*.styl', ['stylus']); 39 | }); 40 | 41 | // Default tasks 42 | global.gulp.task('default', ['watch']); 43 | global.gulp.task('build', gulpsync.sync(tasks)); 44 | global.gulp.task('dist', gulpsync.sync(tasks)); -------------------------------------------------------------------------------- /src/scripts/cf/ConversationalFormDocs.ts: -------------------------------------------------------------------------------- 1 | // Docs version 1.0.0 2 | 3 | interface Window { 4 | conversationalFormDocs: any; 5 | } 6 | 7 | // declare module cf{ 8 | // 9 | // } 10 | 11 | // interface cf{ 12 | // ConversationalForm: any; 13 | // } 14 | 15 | // export type ConversationalForm = any; 16 | // interface ConversationalForm = any; 17 | // declare var ConversationalForm: any; 18 | class ConversationalForm {} 19 | 20 | class ConversationalFormDocs{ 21 | private static instance: ConversationalFormDocs 22 | 23 | private cf: any; 24 | /** 25 | * 26 | * @type HTMLElement 27 | */ 28 | private el: HTMLElement; 29 | private introTimer: any = 0; 30 | private h1writer: H1Writer; 31 | constructor(){ 32 | this.el = document.querySelector("main.content"); 33 | 34 | const isDevelopment: boolean = document.getElementById("conversational-form-development") !== null; 35 | if(isDevelopment) 36 | this.el.classList.add("development"); 37 | 38 | this.h1writer = new H1Writer({ 39 | el: document.getElementById("writer") 40 | }) 41 | 42 | const isMenuVisible = window.getComputedStyle(document.getElementById("small-screen-menu")).getPropertyValue("display") != "none"; 43 | if(isMenuVisible) 44 | this.introFlow1(); 45 | else 46 | this.introFlow2(); 47 | } 48 | 49 | /** 50 | * @name introFlow1 51 | * flow for small screens 52 | */ 53 | private introFlow1(): void { 54 | const isDevelopment: boolean = document.getElementById("conversational-form-development") !== null; 55 | 56 | this.introTimer = setTimeout(() => { 57 | this.toggleMenuState(); 58 | this.h1writer.start(); 59 | 60 | this.introTimer = setTimeout(() => { 61 | this.toggleConversation() 62 | }, isDevelopment ? 0 : 2500); 63 | }, isDevelopment ? 0 : 500); 64 | } 65 | 66 | /** 67 | * @name introFlow2 68 | * flow for larger screens 69 | */ 70 | private introFlow2(): void { 71 | const isDevelopment: boolean = document.getElementById("conversational-form-development") !== null; 72 | 73 | this.h1writer.start(); 74 | 75 | this.introTimer = setTimeout(() => { 76 | document.getElementById("info").classList.add('show'); 77 | 78 | this.introTimer = setTimeout(() => { 79 | 80 | document.querySelector("section[role='form']").classList.add('show'); 81 | document.getElementById("cf-toggle-btn").classList.add('show'); 82 | 83 | this.introTimer = setTimeout(() => { 84 | this.toggleConversation() 85 | }, isDevelopment ? 0 : 1500); 86 | }, isDevelopment ? 0 : 3000); 87 | }, isDevelopment ? 0 : 1500); 88 | } 89 | 90 | public toggleMenuState(){ 91 | const open = this.el.classList.toggle('menu-toggle', !this.el.classList.contains('menu-toggle')); 92 | 93 | if(open){ 94 | this.el.classList.remove('cf-toggle'); 95 | } 96 | 97 | return false; 98 | } 99 | 100 | public toggleConversation(){ 101 | clearTimeout(this.introTimer); 102 | 103 | if(!this.el.classList.contains('cf-toggle')){ 104 | 105 | if(!this.cf){ 106 | this.cf = new ( window).cf.ConversationalForm({ 107 | formEl: document.getElementById("cf-form"), 108 | context: document.getElementById("cf-context"), 109 | robotImage: "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIyMHB4IiB2aWV3Qm94PSIwIDAgMjAgMjAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZyBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzY0LjAwMDAwMCwgLTUzMC4wMDAwMDApIiBmaWxsPSIjMjIyMjIyIj4KICAgICAgICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzUzLjAwMDAwMCwgNTE5LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPHJlY3QgeD0iMTEiIHk9IjExIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvcmVjdD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+", 110 | userImage: "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMjBweCIgaGVpZ2h0PSIxNnB4IiB2aWV3Qm94PSIwIDAgMjAgMTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZyBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTM3MS4wMDAwMDAsIC02MTAuMDAwMDAwKSIgZmlsbD0iI0ZGRkZGRiI+CiAgICAgICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyNzQuMDAwMDAwLCA1OTkuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cG9seWdvbiBwb2ludHM9IjEwNyAxMSAxMTcgMjcgOTcgMjciPjwvcG9seWdvbj4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+", 111 | submitCallback: () => { 112 | 113 | }, 114 | flowStepCallback: (dto: any, success: () => void, error: () => void,) => { 115 | if(dto.tag.domElement){ 116 | if(dto.tag.domElement.getAttribute("name") == "repeat"){ 117 | location.reload(); 118 | }else if(dto.tag.domElement.getAttribute("name") == "submit-form"){ 119 | const xhr: XMLHttpRequest = new XMLHttpRequest(); 120 | xhr.addEventListener("load", () =>{ 121 | this.cf.addRobotChatResponse("We received your submission 🙌"); 122 | success(); 123 | }); 124 | xhr.open('POST', document.getElementById("cf-form").getAttribute("action")); 125 | xhr.setRequestHeader("accept", "application/javascript"); 126 | xhr.setRequestHeader("Content-Type", "application/json"); 127 | xhr.send(JSON.stringify(this.cf.getFormData(true))); 128 | }else{ 129 | success() 130 | } 131 | }else{ 132 | success() 133 | } 134 | } 135 | }); 136 | } 137 | 138 | this.cf.focus(); 139 | 140 | setTimeout(() =>{ 141 | this.el.classList.remove('menu-toggle'); 142 | this.el.classList.add('cf-toggle') 143 | }, 10); 144 | }else{ 145 | this.el.classList.remove('cf-toggle'); 146 | } 147 | 148 | 149 | return false; 150 | } 151 | 152 | public static start(){ 153 | if(!ConversationalFormDocs.instance) 154 | window.conversationalFormDocs = new ConversationalFormDocs(); 155 | } 156 | } 157 | 158 | class H1Writer{ 159 | private progress: number = 0; 160 | private progressTarget: number = 0; 161 | private str: string = ""; 162 | private strs: Array = ["...", "TBD"]; 163 | 164 | /** 165 | * 166 | * @type HTMLElement 167 | */ 168 | private el: HTMLElement; 169 | private rAF: number; 170 | private step: number = 0; 171 | constructor(options: any){ 172 | this.el = options.el 173 | this.strs[1] = this.el.innerHTML; 174 | this.el.innerHTML = ""; 175 | this.el.classList.add("show"); 176 | } 177 | 178 | public start(){ 179 | this.progress = 0; 180 | this.progressTarget = 1; 181 | this.str = this.strs[this.step]; 182 | this.render() 183 | } 184 | 185 | private nextStep(){ 186 | if(this.progressTarget == 0){ 187 | this.step++; 188 | } 189 | 190 | this.str = this.strs[this.step]; 191 | this.progressTarget = this.progressTarget == 0 ? 1 : 0; 192 | this.render() 193 | } 194 | 195 | private render(){ 196 | this.progress += (this.progressTarget - this.progress) * (this.step == 0 ? 0.15 : 0.09); 197 | const out: string = this.str.substr(0, Math.round(this.progress * this.str.length)); 198 | 199 | this.el.innerHTML = out; 200 | 201 | if(Math.abs(this.progress - this.progressTarget) <= 0.01){ 202 | cancelAnimationFrame(this.rAF); 203 | if(this.step < 1){ 204 | setTimeout(() => { 205 | this.nextStep(); 206 | }, 500); 207 | } 208 | } 209 | else 210 | this.rAF = window.requestAnimationFrame(() => this.render()); 211 | } 212 | } 213 | 214 | if(document.readyState == "complete"){ 215 | // if document alread instantiated, usually this happens if Conversational Form is injected through JS 216 | ConversationalFormDocs.start(); 217 | }else{ 218 | // await for when document is ready 219 | window.addEventListener("load", () =>{ 220 | ConversationalFormDocs.start(); 221 | }, false); 222 | } -------------------------------------------------------------------------------- /src/scripts/cf/ConversationalFormExamples.ts: -------------------------------------------------------------------------------- 1 | // Docs version 1.0.0 2 | 3 | interface Window { 4 | conversationalFormExamples: any; 5 | } 6 | 7 | class ConversationalFormExamples{ 8 | private static instance: ConversationalFormExamples 9 | /** 10 | * 11 | * @type HTMLElement 12 | */ 13 | private el: HTMLElement; 14 | private introTimer: any = 0; 15 | private h1writer: H1ExamplesWriter; 16 | private hasCalledExamplesInit: boolean = false; 17 | constructor(){ 18 | this.el = document.querySelector("main.content"); 19 | 20 | const isDevelopment: boolean = document.getElementById("conversational-form-development") !== null; 21 | if(isDevelopment) 22 | this.el.classList.add("development"); 23 | 24 | this.h1writer = new H1ExamplesWriter({ 25 | el: document.getElementById("writer") 26 | }) 27 | 28 | const isMenuVisible = window.getComputedStyle(document.getElementById("small-screen-menu")).getPropertyValue("display") != "none"; 29 | if(isMenuVisible) 30 | this.introFlow1(); 31 | else 32 | this.introFlow2(); 33 | } 34 | 35 | /** 36 | * @name introFlow1 37 | * flow for small screens 38 | */ 39 | private introFlow1(): void { 40 | const isDevelopment: boolean = document.getElementById("conversational-form-development") !== null; 41 | 42 | this.introTimer = setTimeout(() => { 43 | this.toggleMenuState(); 44 | this.h1writer.start(); 45 | 46 | this.introTimer = setTimeout(() => { 47 | if(!document.getElementById("examples-script").getAttribute("manual-init")) 48 | this.toggleConversation() 49 | }, isDevelopment ? 0 : 2500); 50 | }, isDevelopment ? 0 : 500); 51 | } 52 | 53 | /** 54 | * @name introFlow2 55 | * flow for larger screens 56 | */ 57 | private introFlow2(): void { 58 | const isDevelopment: boolean = document.getElementById("conversational-form-development") !== null; 59 | 60 | this.h1writer.start(); 61 | 62 | this.introTimer = setTimeout(() => { 63 | document.getElementById("info").classList.add('show'); 64 | 65 | this.introTimer = setTimeout(() => { 66 | 67 | document.querySelector("section[role='form']").classList.add('show'); 68 | document.getElementById("cf-toggle-btn").classList.add('show'); 69 | 70 | this.introTimer = setTimeout(() => { 71 | if(!document.getElementById("examples-script").getAttribute("manual-init")) 72 | this.toggleConversation() 73 | }, isDevelopment ? 0 : 1500); 74 | }, isDevelopment ? 0 : 3000); 75 | }, isDevelopment ? 0 : 1500); 76 | } 77 | 78 | public toggleMenuState(){ 79 | const open = this.el.classList.toggle('menu-toggle', !this.el.classList.contains('menu-toggle')); 80 | 81 | if(open){ 82 | this.el.classList.remove('cf-toggle'); 83 | } 84 | 85 | return false; 86 | } 87 | 88 | public toggleConversation(){ 89 | if(!this.hasCalledExamplesInit && ( window).initExample){ 90 | ( window).initExample(); 91 | this.hasCalledExamplesInit = true; 92 | } 93 | clearTimeout(this.introTimer); 94 | 95 | if(!this.el.classList.contains('cf-toggle')){ 96 | setTimeout(() =>{ 97 | this.el.classList.remove('menu-toggle'); 98 | this.el.classList.add('cf-toggle') 99 | }, 10); 100 | }else{ 101 | this.el.classList.remove('cf-toggle'); 102 | } 103 | 104 | return false; 105 | } 106 | 107 | public static start(){ 108 | if(!ConversationalFormExamples.instance) 109 | window.conversationalFormExamples = new ConversationalFormExamples(); 110 | } 111 | } 112 | 113 | class H1ExamplesWriter{ 114 | private progress: number = 0; 115 | private progressTarget: number = 0; 116 | private str: string = ""; 117 | private strs: Array = ["...", "TBD"]; 118 | 119 | /** 120 | * 121 | * @type HTMLElement 122 | */ 123 | private el: HTMLElement; 124 | private rAF: number; 125 | private step: number = 0; 126 | constructor(options: any){ 127 | this.el = options.el 128 | this.strs[1] = this.el.innerHTML; 129 | this.el.innerHTML = ""; 130 | this.el.classList.add("show"); 131 | } 132 | 133 | public start(){ 134 | this.progress = 0; 135 | this.progressTarget = 1; 136 | this.str = this.strs[this.step]; 137 | this.render() 138 | } 139 | 140 | private nextStep(){ 141 | if(this.progressTarget == 0){ 142 | this.step++; 143 | } 144 | 145 | this.str = this.strs[this.step]; 146 | this.progressTarget = this.progressTarget == 0 ? 1 : 0; 147 | this.render() 148 | } 149 | 150 | private render(){ 151 | this.progress += (this.progressTarget - this.progress) * (this.step == 0 ? 0.15 : 0.09); 152 | const out: string = this.str.substr(0, Math.round(this.progress * this.str.length)); 153 | 154 | this.el.innerHTML = out; 155 | 156 | if(Math.abs(this.progress - this.progressTarget) <= 0.01){ 157 | cancelAnimationFrame(this.rAF); 158 | if(this.step < 1){ 159 | setTimeout(() => { 160 | this.nextStep(); 161 | }, 500); 162 | } 163 | } 164 | else 165 | this.rAF = window.requestAnimationFrame(() => this.render()); 166 | } 167 | } 168 | 169 | if(document.readyState == "complete"){ 170 | // if document alread instantiated, usually this happens if Conversational Form is injected through JS 171 | ConversationalFormExamples.start(); 172 | }else{ 173 | // await for when document is ready 174 | window.addEventListener("load", () =>{ 175 | ConversationalFormExamples.start(); 176 | }, false); 177 | } -------------------------------------------------------------------------------- /src/scripts/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "globalDependencies": { 3 | } 4 | } 5 | -------------------------------------------------------------------------------- /src/scripts/typings/index.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/space10-community/conversational-form-docs/50e5655220d430a9f83ccc2a086ce9cf146c6c2a/src/scripts/typings/index.d.ts -------------------------------------------------------------------------------- /src/styles/cf/_cf-docs-variables.styl: -------------------------------------------------------------------------------- 1 | $anim-easeIn = cubic-bezier(0.550, 0.055, 0.675, 0.190) 2 | $anim-easeOut = cubic-bezier(0.215, 0.610, 0.355, 1.000) 3 | $anim-easeInOut = cubic-bezier(0.645, 0.045, 0.355, 1.000) 4 | $anim-easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275) 5 | $anim-time = 0.75s 6 | $anim-time-2 = $anim-time * 0.5 7 | 8 | $breakpoint-1 = 769px 9 | 10 | $color-black = #222222 11 | $color-white = white 12 | $color-green = #1ED97B 13 | 14 | $zIndex-high = 500 15 | $zIndex-middle = 250 16 | $zIndex-low = 50 17 | 18 | $menu-height = 61px 19 | 20 | $font-weight-regular = 400 21 | $font-weight-bold = 900 -------------------------------------------------------------------------------- /src/styles/cf/_cf-variables.styl: -------------------------------------------------------------------------------- 1 | $anim-easeIn = cubic-bezier(0.550, 0.055, 0.675, 0.190) 2 | $anim-easeOut = cubic-bezier(0.215, 0.610, 0.355, 1.000) 3 | $anim-easeInOut = cubic-bezier(0.645, 0.045, 0.355, 1.000) 4 | $anim-easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275) 5 | $anim-time = 0.75s 6 | 7 | $input-field-height = 45px 8 | 9 | $breakpoint-1 = 768px 10 | 11 | $color-dark-blue = #0D83FF 12 | $color-chat-reponse-default-bg = #f8f8f8 13 | $color-chat-reponse-user-bg = #e6f3fe 14 | $color-input-error-bg = #fef0f0 15 | $color-chat-reponse-default-text = #aaafb0 16 | $color-chat-reponse-user-text = #1b9bfc 17 | $color-input-error-text = #fe8d84 18 | $color-input-text = #acb2b6 -------------------------------------------------------------------------------- /src/styles/cf/cf-theming.styl: -------------------------------------------------------------------------------- 1 | @import "_cf-docs-variables" 2 | 3 | $color-cf-black = #222222 4 | $color-cf-grey = #EBEBEB 5 | $color-cf-white = white 6 | 7 | main.content 8 | .conversational-form 9 | font-family Helvetica Neue, Helvetica 10 | font-style normal 11 | 12 | cf-chat-response 13 | padding-top 0px 14 | min-width 200px 15 | +below($breakpoint-1) 16 | max-width 83% 17 | 18 | text 19 | font-weight $font-weight-bold 20 | min-height 42px 21 | font-size 13px 22 | 23 | thumb 24 | background-color $color-cf-grey 25 | height 42px 26 | width 42px 27 | 28 | &:not(:last-of-type) 29 | margin-bottom 10px 30 | 31 | cf-chat-response.robot 32 | padding-left 48px 33 | 34 | text 35 | background $color-cf-grey 36 | color $color-cf-black 37 | border-radius 4px 20px 20px 20px 38 | 39 | thumb 40 | background-color $color-cf-grey 41 | background-size 20px 20px 42 | background-repeat no-repeat 43 | 44 | cf-chat-response.user 45 | padding-right 48px 46 | 47 | text 48 | background $color-cf-black 49 | color $color-cf-white 50 | border-radius 20px 4px 20px 20px 51 | 52 | thumb 53 | background-color $color-cf-black 54 | background-size 20px 16px 55 | background-repeat no-repeat 56 | background-position 11px 12px 57 | 58 | cf-input input, cf-input textarea 59 | border-radius 40px 60 | min-height 57px 61 | font-size 14px 62 | +above($breakpoint-1) 63 | font-size 16px 64 | padding 19px 60px 19px 40px 65 | height 56px 66 | color rgba($color-cf-black, 0.4) 67 | font-weight $font-weight-bold 68 | &:not(:focus) 69 | box-shadow 0 0 1px rgba(58, 58, 58, 0.5) 70 | 71 | 72 | cf-input-button 73 | background $color-cf-black 74 | height 42px 75 | width 42px 76 | border none 77 | 78 | .cf-icon-progress 79 | background-image url("data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMThweCIgaGVpZ2h0PSIxOXB4IiB2aWV3Qm94PSIwIDAgMTggMTkiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8ZyBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTM3Mi4wMDAwMDAsIC05NDUuMDAwMDAwKSIgc3Ryb2tlPSIjRkZGRkZGIiBzdHJva2Utd2lkdGg9IjIiPgogICAgICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3NTEuMDAwMDAwLCA5MjcuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MjIuMDAwMDAwLCAxOS4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOC4xNDAzNTA4OCwyLjEwOTE4MTE0IEw4LjE0MDM1MDg4LDE2LjA4MDkzODUiIGlkPSJMaW5lIiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlsaW5lIGlkPSJSZWN0YW5nbGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuOTkzODAzLCA4LjA2ODc0NSkgcm90YXRlKC0zMTUuMDAwMDAwKSB0cmFuc2xhdGUoLTcuOTkzODAzLCAtOC4wNjg3NDUpICIgcG9pbnRzPSIyLjYyNTkxMzI4IDEzLjQ4Njk1OCAyLjYyNTkxMzI4IDIuNjUwNTMxMjEgMi42MjU5MTMyOCAyLjY1MDUzMTIxIDEzLjM2MTY5MjEgMi42NTA1MzEyMSI+PC9wb2x5bGluZT4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+") 80 | background-size 18px 19px 81 | 82 | &.loading:after 83 | border 2px solid #1ed97b 84 | 85 | .cf-button 86 | color $color-cf-black 87 | border-color #DDDDDD 88 | transition border-color $anim-time $anim-easeOut, color $anim-time $anim-easeOut 89 | background none !important 90 | font-weight $font-weight-bold 91 | line-height 1.2 92 | 93 | > div 94 | padding 14px 24px 95 | 96 | cf-radio 97 | background rgba($color-cf-black, 0.2) 98 | 99 | &.highlight, &:focus, &:hover, &[checked="checked"], &.selected 100 | border-color darken(#DDDDDD, 50%) 101 | color lighten($color-cf-black, 25%) 102 | 103 | cf-radio, cf-radio, cf-radio 104 | background $color-cf-black 105 | 106 | cf-list-button:after 107 | background-image none 108 | background black 109 | width 5px 110 | height 5px 111 | border-radius 50% 112 | 113 | -------------------------------------------------------------------------------- /src/styles/cf/docs.styl: -------------------------------------------------------------------------------- 1 | @import "nib" 2 | @import "rupture" 3 | @import "_cf-docs-variables" 4 | 5 | // boilerplate 6 | global-reset() 7 | 8 | html 9 | overflow-y auto 10 | 11 | body 12 | background $color-black 13 | 14 | body, html 15 | position relative 16 | width 100% 17 | height 100% 18 | padding 0px 19 | margin 0px 20 | 21 | main.content 22 | font-family Helvetica Neue, Helvetica 23 | font-style normal 24 | -webkit-font-smoothing antialiased 25 | min-height 100% 26 | height auto 27 | width 100% 28 | position relative 29 | overflow hidden 30 | display block 31 | 32 | * 33 | -webkit-tap-highlight-color rgba(255, 255, 255, 0) 34 | -webkit-touch-callout none 35 | -webkit-user-select none 36 | -khtml-user-select none 37 | -moz-user-select none 38 | -ms-user-select none 39 | user-select none 40 | 41 | *, *:before, *:after 42 | box-sizing border-box 43 | outline none 44 | 45 | a, a:active, a:focus 46 | color currentColor 47 | 48 | .switch-btn#cf-toggle-btn 49 | +above($breakpoint-1) 50 | position absolute 51 | top 40px 52 | z-index $zIndex-high 53 | right 32px 54 | transform translateX(400px) 55 | will-change transform 56 | transition transform $anim-time-2 $anim-easeOut 57 | 58 | &.show 59 | transform translateX(0px) 60 | 61 | +below($breakpoint-1) 62 | display none 63 | -------------------------------------------------------------------------------- /src/styles/cf/mixins/_cf-mixins.styl: -------------------------------------------------------------------------------- 1 | responsivePXValue(min, max, minSize = 320, maxSize = 1600) 2 | //calc( min + ((max - min) * ((100vw - minSize) / (maxSize - minSize)))) 3 | s('calc(%spx + ((%s - %s) * ((100vw - %spx) / (%s - %s))))', min, max, min, minSize, maxSize, minSize) -------------------------------------------------------------------------------- /src/styles/cf/ui/section-cf-context.styl: -------------------------------------------------------------------------------- 1 | @import "../_cf-docs-variables" 2 | 3 | main.content 4 | &.cf-toggle:not(.menu-toggle) 5 | section[role="cf-context"] 6 | pointer-events auto 7 | opacity 1 8 | 9 | section[role="cf-context"] 10 | position absolute 11 | z-index $zIndex-middle 12 | pointer-events none 13 | overflow hidden 14 | height 100% 15 | width 100% 16 | top 0px 17 | left 0px 18 | opacity 0 19 | will-change opacity 20 | transition opacity $anim-time-2 $anim-easeOut 21 | 22 | +above($breakpoint-1) 23 | width 50% 24 | z-index $zIndex-high - 1 25 | right 0px 26 | left auto 27 | 28 | .close-btn 29 | position absolute 30 | z-index $zIndex-high 31 | right 24px 32 | top 18px 33 | width 24px 34 | height 24px 35 | 36 | svg 37 | width 100% 38 | height 100% 39 | -------------------------------------------------------------------------------- /src/styles/cf/ui/section-form.styl: -------------------------------------------------------------------------------- 1 | @import "../_cf-docs-variables" 2 | @import "../mixins/_cf-mixins.styl" 3 | 4 | main.content 5 | section[role="form"] 6 | position absolute 7 | background $color-white 8 | top 0px 9 | left 0px 10 | z-index $zIndex-low 11 | height 100% 12 | width 100% 13 | padding 27px 14 | padding-top $menu-height + 27px 15 | display flex 16 | flex-flow row 17 | justify-content flex-start 18 | 19 | +above($breakpoint-1) 20 | padding 37px 40px 21 | width 50vw 22 | z-index $zIndex-middle 23 | right 0px 24 | left auto 25 | will-change opacity 26 | transition opacity $anim-time-2 $anim-easeOut 27 | opacity 0 28 | 29 | &.show 30 | opacity 1 31 | 32 | .close-btn 33 | position absolute 34 | z-index $zIndex-high - 1 35 | right 24px 36 | top 18px 37 | width 24px 38 | height 24px 39 | 40 | svg 41 | width 100% 42 | height 100% 43 | 44 | form 45 | align-self flex-end 46 | width 100% 47 | 48 | fieldset 49 | margin-bottom 20px 50 | max-width 400px 51 | 52 | &:nth-child(6), &:nth-child(7) 53 | display none 54 | 55 | > * 56 | display block 57 | width 100% 58 | 59 | button 60 | max-width 50px 61 | 62 | label 63 | font-weight $font-weight-bold 64 | font-size responsivePXValue(9, 12) 65 | margin-bottom 4px 66 | 67 | input 68 | padding 8px 69 | 70 | &[type="text"], &[type="email"] 71 | border 1px solid $color-black 72 | 73 | select 74 | -webkit-appearance none 75 | -webkit-border-radius 0px 76 | // from http://stackoverflow.com/a/29151997 77 | background url("data:image/svg+xml;utf8,") 78 | background-repeat no-repeat 79 | background-size 60% 60% 80 | background-position 160% 50% 81 | 82 | padding 8px 83 | 84 | height 31px 85 | font-size responsivePXValue(9, 12) 86 | border-radius 0px 87 | background-color white 88 | border-color black 89 | 90 | .radio 91 | margin-left 30px 92 | -------------------------------------------------------------------------------- /src/styles/cf/ui/section-info.styl: -------------------------------------------------------------------------------- 1 | @import "../_cf-docs-variables" 2 | @import "../mixins/_cf-mixins.styl" 3 | 4 | main.content 5 | &.menu-toggle:not(.cf-toggle) 6 | section[role="info"] 7 | transform translateX(0%) 8 | 9 | section[role="info"] 10 | background $color-black 11 | position absolute 12 | left 0px 13 | top 0px 14 | z-index $zIndex-low + 1 15 | color $color-white 16 | height 100% 17 | width 100% 18 | transform translateX(-100%) 19 | will-change transform 20 | transition transform $anim-time-2 $anim-easeOut 21 | padding 27px 22 | 23 | a 24 | opacity 1 25 | +above($breakpoint-1) 26 | will-change opacity 27 | transition opacity $anim-time $anim-easeOut 28 | 29 | &:hover 30 | opacity 0.5 31 | 32 | +below($breakpoint-1) 33 | transform translateX(100%) 34 | z-index $zIndex-high - 1 35 | 36 | +above($breakpoint-1) 37 | padding 37px 40px 38 | transform translateX(0%) 39 | 40 | will-change opacity 41 | transition opacity $anim-time $anim-easeOut 42 | 43 | > article h1 44 | opacity 0 45 | &.show 46 | opacity 1 47 | 48 | .github-button__outer 49 | visibility hidden 50 | 51 | > h3, > article h2, > article .github-button__outer iframe, footer > h3, footer > a svg 52 | will-change opacity 53 | transition opacity $anim-time $anim-easeOut 54 | opacity 0 55 | 56 | > h3 57 | transition-delay 2s 58 | 59 | > article 60 | > h2 61 | transition-delay 0.5s 62 | > .github-button__outer iframe:nth-child(1) 63 | transition-delay 0.7s 64 | > .github-button__outer iframe:nth-child(2) 65 | transition-delay 0.9s 66 | 67 | footer > h3 68 | transition-delay 2s 69 | footer > a svg 70 | transition-delay 3s 71 | 72 | &.show 73 | .github-button__outer 74 | visibility visible 75 | 76 | > h3, > article h2 77 | opacity 0.7 78 | > article .github-button__outer iframe, footer > h3, footer > a svg 79 | opacity 1 80 | 81 | .close-btn 82 | display none 83 | 84 | +below($breakpoint-1) 85 | .close-btn 86 | display block 87 | position absolute 88 | z-index $zIndex-high - 1 89 | right 24px 90 | top 18px 91 | width 24px 92 | height 24px 93 | border none 94 | background none 95 | padding 0 96 | margin 0 97 | 98 | svg 99 | width 100% 100 | height 100% 101 | 102 | > h3 103 | line-height 1.25 104 | font-weight $font-weight-bold 105 | font-size responsivePXValue(9, 12) 106 | 107 | article 108 | position absolute 109 | bottom 27px 110 | width calc(100% - 54px) 111 | +above($breakpoint-1) 112 | bottom 37px 113 | width calc(50% - 80px) 114 | 115 | h1 116 | line-height 1.1 117 | letter-spacing 0.5px 118 | font-weight $font-weight-bold 119 | font-size responsivePXValue(35, 50) 120 | padding-right 20px 121 | max-width 800px 122 | 123 | h2 124 | line-height 1.2 125 | letter-spacing -0.1px 126 | font-weight $font-weight-regular 127 | font-size responsivePXValue(12, 13) 128 | max-width responsivePXValue(270, 320) 129 | margin-top responsivePXValue(11, 30) 130 | margin-bottom responsivePXValue(22, 60) 131 | 132 | .github-button__outer 133 | height 28px 134 | 135 | iframe:first-of-type 136 | margin-right 10px 137 | 138 | 139 | footer 140 | width 100% 141 | position relative 142 | margin-top responsivePXValue(65, 138) 143 | 144 | h3 145 | font-weight $font-weight-bold 146 | font-size responsivePXValue(11, 13) 147 | 148 | > a 149 | position absolute 150 | right 0px 151 | top 0px 152 | height 16px 153 | width responsivePXValue(51, 58) 154 | 155 | svg 156 | width 100% 157 | height 100% 158 | 159 | -------------------------------------------------------------------------------- /src/styles/cf/ui/sticky-menu.styl: -------------------------------------------------------------------------------- 1 | @import "../_cf-docs-variables" 2 | @import "../mixins/_cf-mixins.styl" 3 | 4 | main.content 5 | &.menu-toggle 6 | > menu 7 | transform translateY(-100%) 8 | 9 | > menu 10 | background $color-black 11 | position fixed 12 | z-index $zIndex-high 13 | padding 0px 14 | margin 0px 15 | height $menu-height 16 | width 100% 17 | color $color-white 18 | left 0px 19 | top 0px 20 | 21 | will-change transform 22 | transition transform $anim-time-2 $anim-easeOut 23 | 24 | +above($breakpoint-1) 25 | display none 26 | 27 | h2 28 | font-weight $font-weight-bold 29 | transform translateY(-50%) 30 | position absolute 31 | left 24px 32 | top 50% 33 | font-size responsivePXValue(14, 16) 34 | 35 | .switch-btn 36 | position absolute 37 | right 63px 38 | top 16px 39 | 40 | .hamburger-btn 41 | position absolute 42 | height 14px 43 | width 29px 44 | right 21px 45 | top 23px 46 | svg 47 | width 100% 48 | height 100% -------------------------------------------------------------------------------- /src/styles/cf/ui/switch.styl: -------------------------------------------------------------------------------- 1 | @import "../_cf-docs-variables" 2 | 3 | main.content 4 | &.cf-toggle 5 | .switch-btn 6 | &:after 7 | opacity 0 8 | 9 | &:before 10 | opacity 1 11 | 12 | .switch 13 | .slider 14 | background-color $color-green 15 | 16 | .slider 17 | box-shadow 0 0 1px $color-green 18 | 19 | .slider:before 20 | transform translateX(26px) 21 | 22 | +above($breakpoint-1) 23 | transform translateX(39px) 24 | 25 | .switch-btn 26 | font-size 13px 27 | font-weight $font-weight-bold 28 | border none 29 | background none 30 | padding 0 31 | margin 0 32 | 33 | &:after 34 | content attr(data-label) 35 | opacity 1 36 | 37 | &:before 38 | content attr(data-label-toggled) 39 | opacity 0 40 | 41 | &:after, &:before 42 | display block 43 | position absolute 44 | left -11px 45 | top 50% 46 | transform translateX(-100%) translateY(-50%) 47 | white-space nowrap 48 | will-change opacity 49 | transition opacity $anim-time-2 $anim-easeOut 50 | 51 | .switch 52 | position relative 53 | display inline-block 54 | width 56px 55 | height 28px 56 | 57 | +above($breakpoint-1) 58 | width 80px 59 | height 40px 60 | 61 | padding 0 62 | margin 0 63 | border none 64 | background none 65 | cursor pointer 66 | 67 | 68 | input 69 | display none 70 | 71 | .slider 72 | position absolute 73 | pointer-events none 74 | top 0 75 | left 0 76 | right 0 77 | bottom 0 78 | background-color #ccc 79 | will-change transform, background-color 80 | transition transform $anim-time-2 $anim-easeOut, background-color $anim-time-2 $anim-easeOut 81 | 82 | &.round 83 | border-radius 34px 84 | 85 | &:before 86 | border-radius 50% 87 | 88 | &:before 89 | position absolute 90 | content "" 91 | height 20px 92 | width 20px 93 | left 4px 94 | bottom 4px 95 | 96 | +above($breakpoint-1) 97 | height 30px 98 | width 30px 99 | left 5px 100 | bottom 5px 101 | 102 | background-color white 103 | transition transform $anim-time-2 $anim-easeOut -------------------------------------------------------------------------------- /src/styles/examples-boilerplate.styl: -------------------------------------------------------------------------------- 1 | @import "nib" 2 | @import "rupture" 3 | 4 | @import "cf/_cf-docs-variables" 5 | @import "cf/mixins/_cf-mixins.styl" 6 | 7 | // boilerplate 8 | // we use docs as a foundation 9 | 10 | // TBD 11 | .form-outer 12 | display flex 13 | 14 | > #form 15 | align-self flex-end 16 | 17 | > h2 18 | position absolute 19 | bottom 20px 20 | left 20px --------------------------------------------------------------------------------