From 60fff24431e8b6bd27d3aa614fdc96674820d543 Mon Sep 17 00:00:00 2001 From: Ronald Bourret Date: Wed, 26 Nov 2025 22:45:24 +0000 Subject: [PATCH 01/10] feat: Initial commit of CSS codelab solution --- .../css-codelab/complete-code/classic.css | 142 ++++ .../css-codelab/complete-code/halloween.css | 184 ++++ examples/css-codelab/complete-code/index.html | 42 + examples/css-codelab/complete-code/index.js | 13 + examples/css-codelab/complete-code/toolbox.js | 800 ++++++++++++++++++ examples/css-codelab/starter-code/classic.css | 142 ++++ examples/css-codelab/starter-code/index.html | 40 + examples/css-codelab/starter-code/index.js | 11 + examples/css-codelab/starter-code/toolbox.js | 786 +++++++++++++++++ 9 files changed, 2160 insertions(+) create mode 100644 examples/css-codelab/complete-code/classic.css create mode 100644 examples/css-codelab/complete-code/halloween.css create mode 100644 examples/css-codelab/complete-code/index.html create mode 100644 examples/css-codelab/complete-code/index.js create mode 100644 examples/css-codelab/complete-code/toolbox.js create mode 100644 examples/css-codelab/starter-code/classic.css create mode 100644 examples/css-codelab/starter-code/index.html create mode 100644 examples/css-codelab/starter-code/index.js create mode 100644 examples/css-codelab/starter-code/toolbox.js diff --git a/examples/css-codelab/complete-code/classic.css b/examples/css-codelab/complete-code/classic.css new file mode 100644 index 000000000..213e20a9d --- /dev/null +++ b/examples/css-codelab/complete-code/classic.css @@ -0,0 +1,142 @@ +/* This file uses CSS to recreate the blocks part + of the classic theme for the thrasos renderer, */ + +/* LOGIC BLOCKS */ + +.logic_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5b80a5; + stroke: #8ca6c0; +} + +.logic_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bdccdb; + stroke: none; +} + +.logic_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5b80a5 !important; +} + +.logic_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bdccdb !important; +} + +/* LOOOP BLOCKS */ + +.loop_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5ba55b; + stroke: #8cc08c; +} + +.loop_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bddbbd; + stroke: none; +} + +.loop_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5ba55b !important; +} + +.loop_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bddbbd !important; +} + +/* MATH BLOCKS */ + +.math_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5b67a5; + stroke: #8c95c0; +} + +.math_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bdc2db; + stroke: none; +} + +.math_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5b67a5 !important; +} + +.math_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bdc2db !important; +} + +/* TEXT BLOCKS */ + +.text_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5ba58c; + stroke: #8cc0af; +} + +.text_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bddbd1; + stroke: none; +} + +.text_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5ba58c !important; +} + +.text_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bddbd1 !important; +} + +/* LIST BLOCKS */ + +.list_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #745ba5; + stroke: #9e8cc0; +} + +.list_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #c7bddb; + stroke: none; +} + +.list_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #745ba5 !important; +} + +.list_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #c7bddb !important; +} + +/* VARIABLE BLOCKS */ + +.variable_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #a55b80; + stroke: #c08ca6; +} + +.variable_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #dbbdcc; + stroke: none; +} + +.variable_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #a55b80 !important; +} + +.variable_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #dbbdcc !important; +} + +/* PROCEDURE BLOCKS */ + +.procedure_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #995ba5; + stroke: #b88cc0; +} +.procedure_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #d6bddb; + stroke: none; +} + +.procedure_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #995ba5 !important; +} + +.procedure_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #d6bddb !important; +} + diff --git a/examples/css-codelab/complete-code/halloween.css b/examples/css-codelab/complete-code/halloween.css new file mode 100644 index 000000000..d7d829bcc --- /dev/null +++ b/examples/css-codelab/complete-code/halloween.css @@ -0,0 +1,184 @@ +/**************/ +/* COMPONENTS */ +/**************/ + +.blocklySvg { + background-color: #ff7518; +} + +.blocklyMutatorBackground { + fill: #ff7518; +} + +.blocklyToolbox { + background-color: #f9c10e; + color: #fff; +} + +.blocklyFlyoutBackground { + fill: #252526; + fill-opacity: 1; +} + +.blocklyFlyoutLabel>.blocklyFlyoutLabelText { + fill: #ccc !important; +} + +.blocklyFlyoutButton>.blocklyText { + fill: #ccc !important; +} + +.blocklyScrollbarHandle { + fill: #ff0000; + fill-opacity: 0.4; +} + +.blocklyInsertionMarker>.blocklyPath { + fill: #fff !important; + fill-opacity: 0.3 !important; + stroke: none; +} + +/**************/ +/* CATEGORIES */ +/**************/ + +.logic_category { + border-left: 8px solid #8b4513; +} + +.logic_category.blocklyToolboxSelected { + background-color: #8b4513 !important; +} + +.loop_category { + border-left: 8px solid #85e21f; +} + +.loop_category.blocklyToolboxSelected { + background-color: #85e21f !important; +} + +.math_category { + border-left: 8px solid #5b67a5; +} + +.math_category.blocklyToolboxSelected { + background-color: #5b67a5 !important; +} + +.text_category { + border-left: 8px solid #fe9b13; +} + +.text_category.blocklyToolboxSelected { + background-color: #fe9b13 !important; +} + +.list_category { + border-left: 8px solid #4a148c; +} + +.list_category.blocklyToolboxSelected { + background-color: #4a148c !important; +} + +.variable_category { + border-left: 8px solid #a55b80; +} + +.variable_category.blocklyToolboxSelected { + background-color: #a55b80 !important; +} + +.procedure_category { + border-left: 8px solid #b88cc0; +} + +.procedure_category.blocklyToolboxSelected { + background-color: #b88cc0 !important; +} + +/**********/ +/* BLOCKS */ +/**********/ + +/* LOGIC BLOCKS */ + +.logic_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #8b4513; + stroke: #C5EAFF; +} + +.logic_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #ff0000; + stroke: none; +} + +.logic_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #8b4513 !important; +} + +.logic_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* LOOP BLOCKS */ + +.loop_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #85E21F; + stroke: #C5EAFF; +} + +.loop_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #ff0000; + stroke: none; +} + +.loop_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #85E21F !important; +} + +.loop_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* TEXT BLOCKS */ + +.text_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #FE9B13; + stroke: #C5EAFF; +} + +.text_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #ff0000; + stroke: none; +} + +.text_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #FE9B13 !important; +} + +.text_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #ff0000 !important; +} + +/* LIST BLOCKS */ + +.list_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #4a148c; + stroke: #CDB6E9; +} + +.list_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #AD7BE9; + stroke: none; +} + +.list_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #4a148c !important; +} + +.list_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #AD7BE9 !important; +} diff --git a/examples/css-codelab/complete-code/index.html b/examples/css-codelab/complete-code/index.html new file mode 100644 index 000000000..86e99a945 --- /dev/null +++ b/examples/css-codelab/complete-code/index.html @@ -0,0 +1,42 @@ + + + + + CSS Codelab + + + + + + + + + + +

CSS Codelab

+
+ + diff --git a/examples/css-codelab/complete-code/index.js b/examples/css-codelab/complete-code/index.js new file mode 100644 index 000000000..dc87f2e5d --- /dev/null +++ b/examples/css-codelab/complete-code/index.js @@ -0,0 +1,13 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + const nullTheme = Blockly.Theme.defineTheme('nullTheme', {}); + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + theme: nullTheme, + renderer: 'thrasos', + }); +} diff --git a/examples/css-codelab/complete-code/toolbox.js b/examples/css-codelab/complete-code/toolbox.js new file mode 100644 index 000000000..f2e48271a --- /dev/null +++ b/examples/css-codelab/complete-code/toolbox.js @@ -0,0 +1,800 @@ +const toolboxCategories = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Logic', + cssConfig: { + row: 'blocklyToolboxCategory logic_category', + }, + contents: [ + { + type: 'controls_if', + kind: 'block', + }, + { + type: 'logic_compare', + kind: 'block', + fields: { + OP: 'EQ', + }, + }, + { + type: 'logic_operation', + kind: 'block', + fields: { + OP: 'AND', + }, + }, + { + type: 'logic_negate', + kind: 'block', + }, + { + type: 'logic_boolean', + kind: 'block', + fields: { + BOOL: 'TRUE', + }, + }, + { + type: 'logic_null', + kind: 'block', + enabled: false, + }, + { + type: 'logic_ternary', + kind: 'block', + }, + ], + }, + { + kind: 'category', + name: 'Loops', + cssConfig: { + row: 'blocklyToolboxCategory loop_category', + }, + contents: [ + { + type: 'controls_repeat_ext', + kind: 'block', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'controls_repeat', + kind: 'block', + enabled: false, + fields: { + TIMES: 10, + }, + }, + { + type: 'controls_whileUntil', + kind: 'block', + fields: { + MODE: 'WHILE', + }, + }, + { + type: 'controls_for', + kind: 'block', + fields: { + VAR: { + name: 'i', + }, + }, + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'controls_forEach', + kind: 'block', + fields: { + VAR: { + name: 'j', + }, + }, + }, + { + type: 'controls_flow_statements', + kind: 'block', + enabled: false, + fields: { + FLOW: 'BREAK', + }, + }, + ], + }, + { + kind: 'category', + name: 'Math', + cssConfig: { + row: 'blocklyToolboxCategory math_category', + }, + contents: [ + { + type: 'math_number', + kind: 'block', + fields: { + NUM: 123, + }, + }, + { + type: 'math_arithmetic', + kind: 'block', + fields: { + OP: 'ADD', + }, + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'math_single', + kind: 'block', + fields: { + OP: 'ROOT', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, + }, + }, + }, + }, + }, + { + type: 'math_trig', + kind: 'block', + fields: { + OP: 'SIN', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, + }, + }, + }, + }, + }, + { + type: 'math_constant', + kind: 'block', + fields: { + CONSTANT: 'PI', + }, + }, + { + type: 'math_number_property', + kind: 'block', + fields: { + PROPERTY: 'EVEN', + }, + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, + }, + }, + }, + }, + }, + { + type: 'math_round', + kind: 'block', + fields: { + OP: 'ROUND', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, + }, + }, + }, + }, + }, + { + type: 'math_on_list', + kind: 'block', + fields: { + OP: 'SUM', + }, + }, + { + type: 'math_modulo', + kind: 'block', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, + }, + }, + }, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'math_constrain', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, + }, + }, + }, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_int', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_float', + kind: 'block', + }, + { + type: 'math_atan2', + kind: 'block', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Text', + cssConfig: { + row: 'blocklyToolboxCategory text_category', + }, + contents: [ + { + type: 'text', + kind: 'block', + fields: { + TEXT: '', + }, + }, + { + type: 'text_join', + kind: 'block', + }, + { + type: 'text_append', + kind: 'block', + fields: { + name: 'item', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_length', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_isEmpty', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_indexOf', + kind: 'block', + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_charAt', + kind: 'block', + fields: { + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_getSubstring', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + STRING: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_changeCase', + kind: 'block', + fields: { + CASE: 'UPPERCASE', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_trim', + kind: 'block', + fields: { + MODE: 'BOTH', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_count', + kind: 'block', + inputs: { + SUB: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_replace', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TO: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_reverse', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + + { + type: 'text_print', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_prompt_ext', + kind: 'block', + fields: { + TYPE: 'TEXT', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Lists', + cssConfig: { + row: 'blocklyToolboxCategory list_category', + }, + contents: [ + { + type: 'lists_create_with', + kind: 'block', + extraState: { + itemCount: 0, + }, + }, + { + type: 'lists_create_with', + kind: 'block', + }, + { + type: 'lists_repeat', + kind: 'block', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + type: 'lists_length', + kind: 'block', + }, + { + type: 'lists_isEmpty', + kind: 'block', + }, + { + type: 'lists_indexOf', + kind: 'block', + + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getIndex', + kind: 'block', + fields: { + MODE: 'GET', + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_setIndex', + kind: 'block', + fields: { + MODE: 'SET', + WHERE: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getSublist', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_split', + kind: 'block', + + fields: { + MODE: 'SPLIT', + }, + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', + }, + }, + }, + }, + }, + { + type: 'lists_sort', + kind: 'block', + + fields: { + TYPE: 'NUMERIC', + DIRECTION: '1', + }, + }, + { + type: 'lists_reverse', + kind: 'block', + }, + ], + }, + { + kind: 'sep', + }, + { + kind: 'category', + name: 'Variables', + custom: 'VARIABLE', + cssConfig: { + row: 'blocklyToolboxCategory variable_category', + }, + }, + { + kind: 'category', + name: 'Functions', + custom: 'PROCEDURE', + cssConfig: { + row: 'blocklyToolboxCategory procedure_category', + }, + }, + ], +}; diff --git a/examples/css-codelab/starter-code/classic.css b/examples/css-codelab/starter-code/classic.css new file mode 100644 index 000000000..213e20a9d --- /dev/null +++ b/examples/css-codelab/starter-code/classic.css @@ -0,0 +1,142 @@ +/* This file uses CSS to recreate the blocks part + of the classic theme for the thrasos renderer, */ + +/* LOGIC BLOCKS */ + +.logic_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5b80a5; + stroke: #8ca6c0; +} + +.logic_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bdccdb; + stroke: none; +} + +.logic_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5b80a5 !important; +} + +.logic_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bdccdb !important; +} + +/* LOOOP BLOCKS */ + +.loop_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5ba55b; + stroke: #8cc08c; +} + +.loop_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bddbbd; + stroke: none; +} + +.loop_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5ba55b !important; +} + +.loop_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bddbbd !important; +} + +/* MATH BLOCKS */ + +.math_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5b67a5; + stroke: #8c95c0; +} + +.math_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bdc2db; + stroke: none; +} + +.math_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5b67a5 !important; +} + +.math_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bdc2db !important; +} + +/* TEXT BLOCKS */ + +.text_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #5ba58c; + stroke: #8cc0af; +} + +.text_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #bddbd1; + stroke: none; +} + +.text_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #5ba58c !important; +} + +.text_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #bddbd1 !important; +} + +/* LIST BLOCKS */ + +.list_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #745ba5; + stroke: #9e8cc0; +} + +.list_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #c7bddb; + stroke: none; +} + +.list_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #745ba5 !important; +} + +.list_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #c7bddb !important; +} + +/* VARIABLE BLOCKS */ + +.variable_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #a55b80; + stroke: #c08ca6; +} + +.variable_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #dbbdcc; + stroke: none; +} + +.variable_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #a55b80 !important; +} + +.variable_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #dbbdcc !important; +} + +/* PROCEDURE BLOCKS */ + +.procedure_blocks:not(.blocklyDisabledPattern)>.blocklyPath { + fill: #995ba5; + stroke: #b88cc0; +} +.procedure_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { + fill: #d6bddb; + stroke: none; +} + +.procedure_blocks>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #995ba5 !important; +} + +.procedure_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { + fill: #d6bddb !important; +} + diff --git a/examples/css-codelab/starter-code/index.html b/examples/css-codelab/starter-code/index.html new file mode 100644 index 000000000..7d0907387 --- /dev/null +++ b/examples/css-codelab/starter-code/index.html @@ -0,0 +1,40 @@ + + + + + CSS Codelab + + + + + + + + +

CSS Codelab

+
+ + diff --git a/examples/css-codelab/starter-code/index.js b/examples/css-codelab/starter-code/index.js new file mode 100644 index 000000000..294d45869 --- /dev/null +++ b/examples/css-codelab/starter-code/index.js @@ -0,0 +1,11 @@ +'use strict'; + +let workspace = null; + +function start() { + // Create main workspace. + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxCategories, + renderer: 'thrasos', + }); +} diff --git a/examples/css-codelab/starter-code/toolbox.js b/examples/css-codelab/starter-code/toolbox.js new file mode 100644 index 000000000..2c10d89dd --- /dev/null +++ b/examples/css-codelab/starter-code/toolbox.js @@ -0,0 +1,786 @@ +const toolboxCategories = { + kind: 'categoryToolbox', + contents: [ + { + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [ + { + type: 'controls_if', + kind: 'block', + }, + { + type: 'logic_compare', + kind: 'block', + fields: { + OP: 'EQ', + }, + }, + { + type: 'logic_operation', + kind: 'block', + fields: { + OP: 'AND', + }, + }, + { + type: 'logic_negate', + kind: 'block', + }, + { + type: 'logic_boolean', + kind: 'block', + fields: { + BOOL: 'TRUE', + }, + }, + { + type: 'logic_null', + kind: 'block', + enabled: false, + }, + { + type: 'logic_ternary', + kind: 'block', + }, + ], + }, + { + kind: 'category', + name: 'Loops', + categorystyle: 'loop_category', + contents: [ + { + type: 'controls_repeat_ext', + kind: 'block', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'controls_repeat', + kind: 'block', + enabled: false, + fields: { + TIMES: 10, + }, + }, + { + type: 'controls_whileUntil', + kind: 'block', + fields: { + MODE: 'WHILE', + }, + }, + { + type: 'controls_for', + kind: 'block', + fields: { + VAR: { + name: 'i', + }, + }, + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'controls_forEach', + kind: 'block', + fields: { + VAR: { + name: 'j', + }, + }, + }, + { + type: 'controls_flow_statements', + kind: 'block', + enabled: false, + fields: { + FLOW: 'BREAK', + }, + }, + ], + }, + { + kind: 'category', + name: 'Math', + categorystyle: 'math_category', + contents: [ + { + type: 'math_number', + kind: 'block', + fields: { + NUM: 123, + }, + }, + { + type: 'math_arithmetic', + kind: 'block', + fields: { + OP: 'ADD', + }, + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + { + type: 'math_single', + kind: 'block', + fields: { + OP: 'ROOT', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, + }, + }, + }, + }, + }, + { + type: 'math_trig', + kind: 'block', + fields: { + OP: 'SIN', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, + }, + }, + }, + }, + }, + { + type: 'math_constant', + kind: 'block', + fields: { + CONSTANT: 'PI', + }, + }, + { + type: 'math_number_property', + kind: 'block', + fields: { + PROPERTY: 'EVEN', + }, + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, + }, + }, + }, + }, + }, + { + type: 'math_round', + kind: 'block', + fields: { + OP: 'ROUND', + }, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, + }, + }, + }, + }, + }, + { + type: 'math_on_list', + kind: 'block', + fields: { + OP: 'SUM', + }, + }, + { + type: 'math_modulo', + kind: 'block', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, + }, + }, + }, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, + }, + }, + }, + }, + { + type: 'math_constrain', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, + }, + }, + }, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_int', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, + }, + }, + }, + }, + }, + { + type: 'math_random_float', + kind: 'block', + }, + { + type: 'math_atan2', + kind: 'block', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Text', + categorystyle: 'text_category', + contents: [ + { + type: 'text', + kind: 'block', + fields: { + TEXT: '', + }, + }, + { + type: 'text_join', + kind: 'block', + }, + { + type: 'text_append', + kind: 'block', + fields: { + name: 'item', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_length', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_isEmpty', + kind: 'block', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_indexOf', + kind: 'block', + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_charAt', + kind: 'block', + fields: { + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_getSubstring', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + STRING: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'text', + }, + }, + }, + }, + }, + }, + { + type: 'text_changeCase', + kind: 'block', + fields: { + CASE: 'UPPERCASE', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_trim', + kind: 'block', + fields: { + MODE: 'BOTH', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_count', + kind: 'block', + inputs: { + SUB: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_replace', + kind: 'block', + inputs: { + FROM: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TO: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + { + type: 'text_reverse', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', + }, + }, + }, + }, + }, + + { + type: 'text_print', + kind: 'block', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + type: 'text_prompt_ext', + kind: 'block', + fields: { + TYPE: 'TEXT', + }, + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + ], + }, + { + kind: 'category', + name: 'Lists', + categorystyle: 'list_category', + contents: [ + { + type: 'lists_create_with', + kind: 'block', + extraState: { + itemCount: 0, + }, + }, + { + type: 'lists_create_with', + kind: 'block', + }, + { + type: 'lists_repeat', + kind: 'block', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, + }, + }, + }, + }, + }, + { + type: 'lists_length', + kind: 'block', + }, + { + type: 'lists_isEmpty', + kind: 'block', + }, + { + type: 'lists_indexOf', + kind: 'block', + + fields: { + END: 'FIRST', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getIndex', + kind: 'block', + fields: { + MODE: 'GET', + WHERE: 'FROM_START', + }, + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_setIndex', + kind: 'block', + fields: { + MODE: 'SET', + WHERE: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_getSublist', + kind: 'block', + fields: { + WHERE1: 'FROM_START', + WHERE2: 'FROM_START', + }, + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: 'list', + }, + }, + }, + }, + }, + }, + { + type: 'lists_split', + kind: 'block', + + fields: { + MODE: 'SPLIT', + }, + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', + }, + }, + }, + }, + }, + { + type: 'lists_sort', + kind: 'block', + + fields: { + TYPE: 'NUMERIC', + DIRECTION: '1', + }, + }, + { + type: 'lists_reverse', + kind: 'block', + }, + ], + }, + { + kind: 'sep', + }, + { + kind: 'category', + name: 'Variables', + custom: 'VARIABLE', + categorystyle: 'variable_category', + }, + { + kind: 'category', + name: 'Functions', + custom: 'PROCEDURE', + categorystyle: 'procedure_category', + }, + ], +}; From 328534b5359cb74cc9a66a6e6384771c71ec5420 Mon Sep 17 00:00:00 2001 From: Ronald Bourret Date: Mon, 1 Dec 2025 17:35:52 +0000 Subject: [PATCH 02/10] fix: Remove classic.css --- .../css-codelab/complete-code/classic.css | 142 ------------------ examples/css-codelab/complete-code/index.html | 1 - examples/css-codelab/complete-code/index.js | 2 - examples/css-codelab/starter-code/classic.css | 142 ------------------ 4 files changed, 287 deletions(-) delete mode 100644 examples/css-codelab/complete-code/classic.css delete mode 100644 examples/css-codelab/starter-code/classic.css diff --git a/examples/css-codelab/complete-code/classic.css b/examples/css-codelab/complete-code/classic.css deleted file mode 100644 index 213e20a9d..000000000 --- a/examples/css-codelab/complete-code/classic.css +++ /dev/null @@ -1,142 +0,0 @@ -/* This file uses CSS to recreate the blocks part - of the classic theme for the thrasos renderer, */ - -/* LOGIC BLOCKS */ - -.logic_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #5b80a5; - stroke: #8ca6c0; -} - -.logic_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #bdccdb; - stroke: none; -} - -.logic_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #5b80a5 !important; -} - -.logic_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #bdccdb !important; -} - -/* LOOOP BLOCKS */ - -.loop_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #5ba55b; - stroke: #8cc08c; -} - -.loop_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #bddbbd; - stroke: none; -} - -.loop_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #5ba55b !important; -} - -.loop_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #bddbbd !important; -} - -/* MATH BLOCKS */ - -.math_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #5b67a5; - stroke: #8c95c0; -} - -.math_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #bdc2db; - stroke: none; -} - -.math_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #5b67a5 !important; -} - -.math_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #bdc2db !important; -} - -/* TEXT BLOCKS */ - -.text_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #5ba58c; - stroke: #8cc0af; -} - -.text_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #bddbd1; - stroke: none; -} - -.text_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #5ba58c !important; -} - -.text_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #bddbd1 !important; -} - -/* LIST BLOCKS */ - -.list_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #745ba5; - stroke: #9e8cc0; -} - -.list_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #c7bddb; - stroke: none; -} - -.list_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #745ba5 !important; -} - -.list_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #c7bddb !important; -} - -/* VARIABLE BLOCKS */ - -.variable_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #a55b80; - stroke: #c08ca6; -} - -.variable_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #dbbdcc; - stroke: none; -} - -.variable_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #a55b80 !important; -} - -.variable_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #dbbdcc !important; -} - -/* PROCEDURE BLOCKS */ - -.procedure_blocks:not(.blocklyDisabledPattern)>.blocklyPath { - fill: #995ba5; - stroke: #b88cc0; -} -.procedure_blocks:not(.blocklyDisabledPattern).blocklyShadow>.blocklyPath { - fill: #d6bddb; - stroke: none; -} - -.procedure_blocks>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #995ba5 !important; -} - -.procedure_blocks.blocklyShadow>.blocklyDropdownField .blocklyDropdownText tspan { - fill: #d6bddb !important; -} - diff --git a/examples/css-codelab/complete-code/index.html b/examples/css-codelab/complete-code/index.html index 86e99a945..1b77752f1 100644 --- a/examples/css-codelab/complete-code/index.html +++ b/examples/css-codelab/complete-code/index.html @@ -6,7 +6,6 @@ -